X_V_MODEL_MALFORMED_EXPRESSION,
X_V_MODEL_ON_SCOPE_VARIABLE,
X_INVALID_EXPRESSION,
+ X_KEEP_ALIVE_INVALID_CHILDREN,
// generic errors
X_PREFIX_ID_NOT_SUPPORTED,
[ErrorCodes.X_V_MODEL_MALFORMED_EXPRESSION]: `v-model value must be a valid JavaScript member expression.`,
[ErrorCodes.X_V_MODEL_ON_SCOPE_VARIABLE]: `v-model cannot be used on v-for or v-slot scope variables because they are not writable.`,
[ErrorCodes.X_INVALID_EXPRESSION]: `Invalid JavaScript expression.`,
+ [ErrorCodes.X_KEEP_ALIVE_INVALID_CHILDREN]: `<KeepAlive> expects exactly one child component.`,
// generic errors
[ErrorCodes.X_PREFIX_ID_NOT_SUPPORTED]: `"prefixIdentifiers" option is not supported in this build of compiler.`,
if (!hasProps) {
args.push(`null`)
}
+
+ if (__DEV__ && nodeType === KEEP_ALIVE && node.children.length > 1) {
+ context.onError(
+ createCompilerError(ErrorCodes.X_KEEP_ALIVE_INVALID_CHILDREN, {
+ start: node.children[0].loc.start,
+ end: node.children[node.children.length - 1].loc.end,
+ source: ''
+ })
+ )
+ }
+
// Portal & KeepAlive should have normal children instead of slots
// Portal is not a real component has dedicated handling in the renderer
// KeepAlive should not track its own deps so that it can be used inside
X_V_MODEL_ON_FILE_INPUT_ELEMENT,
X_V_MODEL_UNNECESSARY_VALUE,
X_V_SHOW_NO_EXPRESSION,
+ X_TRANSITION_INVALID_CHILDREN,
__EXTEND_POINT__
}
[DOMErrorCodes.X_V_MODEL_ARG_ON_ELEMENT]: `v-model argument is not supported on plain elements.`,
[DOMErrorCodes.X_V_MODEL_ON_FILE_INPUT_ELEMENT]: `v-model cannot used on file inputs since they are read-only. Use a v-on:change listener instead.`,
[DOMErrorCodes.X_V_MODEL_UNNECESSARY_VALUE]: `Unnecessary value binding used alongside v-model. It will interfere with v-model's behavior.`,
- [DOMErrorCodes.X_V_SHOW_NO_EXPRESSION]: `v-show is missing expression.`
+ [DOMErrorCodes.X_V_SHOW_NO_EXPRESSION]: `v-show is missing expression.`,
+ [DOMErrorCodes.X_TRANSITION_INVALID_CHILDREN]: `<Transition> expects exactly one child element or component.`
}
import { transformOn } from './transforms/vOn'
import { transformShow } from './transforms/vShow'
import { TRANSITION, TRANSITION_GROUP } from './runtimeHelpers'
+import { warnTransitionChildren } from './transforms/warnTransitionChildren'
export const parserOptions = __BROWSER__
? parserOptionsMinimal
return baseCompile(template, {
...parserOptions,
...options,
- nodeTransforms: [transformStyle, ...(options.nodeTransforms || [])],
+ nodeTransforms: [
+ transformStyle,
+ ...(__DEV__ ? [warnTransitionChildren] : []),
+ ...(options.nodeTransforms || [])
+ ],
directiveTransforms: {
cloak: noopDirectiveTransform,
html: transformVHtml,
--- /dev/null
+import { NodeTransform, NodeTypes, ElementTypes } from '@vue/compiler-core'
+import { TRANSITION } from '../runtimeHelpers'
+import { createDOMCompilerError, DOMErrorCodes } from '../errors'
+
+export const warnTransitionChildren: NodeTransform = (node, context) => {
+ if (
+ node.type === NodeTypes.ELEMENT &&
+ node.tagType === ElementTypes.COMPONENT
+ ) {
+ const component = context.isBuiltInComponent(node.tag)
+ if (
+ component === TRANSITION &&
+ (node.children.length > 1 || node.children[0].type === NodeTypes.FOR)
+ ) {
+ context.onError(
+ createDOMCompilerError(DOMErrorCodes.X_TRANSITION_INVALID_CHILDREN, {
+ start: node.children[0].loc.start,
+ end: node.children[node.children.length - 1].loc.end,
+ source: ''
+ })
+ )
+ }
+ }
+}