mirror of https://github.com/vuejs/core.git
Merge 9759be0451
into 56be3dd4db
This commit is contained in:
commit
ba95fdca8d
|
@ -3453,4 +3453,96 @@ describe('compiler: parse', () => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('vue specific errors', () => {
|
||||||
|
test('error when v-slot used on non-root level <template>', () => {
|
||||||
|
const onError = vi.fn()
|
||||||
|
|
||||||
|
baseParse(
|
||||||
|
`<Bar><template><template #header> Header </template></template></Bar>`,
|
||||||
|
{ onError },
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(onError.mock.calls[0]).toMatchObject([
|
||||||
|
{
|
||||||
|
code: ErrorCodes.X_SLOT_TEMPLATE_NOT_ROOT,
|
||||||
|
loc: {
|
||||||
|
start: { column: 16, line: 1, offset: 15 },
|
||||||
|
end: { column: 53, line: 1, offset: 52 },
|
||||||
|
source: '<template #header> Header </template>',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
test('error when v-slot used on non-root level <template> with v-if', () => {
|
||||||
|
const onError = vi.fn()
|
||||||
|
|
||||||
|
baseParse(
|
||||||
|
`<Bar><template v-if="true"><template #header> Header </template></template></Bar>`,
|
||||||
|
{ onError },
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(onError.mock.calls[0]).toMatchObject([
|
||||||
|
{
|
||||||
|
code: ErrorCodes.X_SLOT_TEMPLATE_NOT_ROOT,
|
||||||
|
loc: {
|
||||||
|
start: { column: 28, line: 1, offset: 27 },
|
||||||
|
end: { column: 65, line: 1, offset: 64 },
|
||||||
|
source: '<template #header> Header </template>',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
test('error when v-slot used on non-root level <template> together with v-if', () => {
|
||||||
|
const onError = vi.fn()
|
||||||
|
|
||||||
|
baseParse(
|
||||||
|
` <div><template v-if="true"><template v-if="true" #item> Header </template></template></div>`,
|
||||||
|
{ onError },
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(onError.mock.calls[0]).toMatchObject([
|
||||||
|
{
|
||||||
|
code: ErrorCodes.X_SLOT_TEMPLATE_NOT_ROOT,
|
||||||
|
loc: {
|
||||||
|
start: { column: 30, line: 1, offset: 29 },
|
||||||
|
end: { column: 77, line: 1, offset: 76 },
|
||||||
|
source: '<template v-if="true" #item> Header </template>',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
test('error when v-slot used on non-root level <template> inside dynamic component', () => {
|
||||||
|
const onError = vi.fn()
|
||||||
|
|
||||||
|
baseParse(
|
||||||
|
`<component is="MyComp"><template><template #item>bar</template></template></component>`,
|
||||||
|
{ onError },
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(onError.mock.calls[0]).toMatchObject([
|
||||||
|
{
|
||||||
|
code: ErrorCodes.X_SLOT_TEMPLATE_NOT_ROOT,
|
||||||
|
loc: {
|
||||||
|
start: { column: 34, line: 1, offset: 33 },
|
||||||
|
end: { column: 64, line: 1, offset: 63 },
|
||||||
|
source: '<template #item>bar</template>',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
test('shouldnt error when v-slot used on non-root level <template> inside dynamic component with casting', () => {
|
||||||
|
const onError = vi.fn()
|
||||||
|
|
||||||
|
baseParse(`<div is="vue:MyComp"><template #item>bar</template></div>`, {
|
||||||
|
onError,
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(onError.mock.calls[0]).toEqual(undefined)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -69,6 +69,7 @@ export enum ErrorCodes {
|
||||||
X_MISSING_INTERPOLATION_END,
|
X_MISSING_INTERPOLATION_END,
|
||||||
X_MISSING_DIRECTIVE_NAME,
|
X_MISSING_DIRECTIVE_NAME,
|
||||||
X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END,
|
X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END,
|
||||||
|
X_SLOT_TEMPLATE_NOT_ROOT,
|
||||||
|
|
||||||
// transform errors
|
// transform errors
|
||||||
X_V_IF_NO_EXPRESSION,
|
X_V_IF_NO_EXPRESSION,
|
||||||
|
@ -151,6 +152,9 @@ export const errorMessages: Record<ErrorCodes, string> = {
|
||||||
'End bracket for dynamic directive argument was not found. ' +
|
'End bracket for dynamic directive argument was not found. ' +
|
||||||
'Note that dynamic directive argument cannot contain spaces.',
|
'Note that dynamic directive argument cannot contain spaces.',
|
||||||
[ErrorCodes.X_MISSING_DIRECTIVE_NAME]: 'Legal directive name was expected.',
|
[ErrorCodes.X_MISSING_DIRECTIVE_NAME]: 'Legal directive name was expected.',
|
||||||
|
[ErrorCodes.X_SLOT_TEMPLATE_NOT_ROOT]:
|
||||||
|
`<template v-slot> can only appear at the root level inside ` +
|
||||||
|
`the receiving component`,
|
||||||
|
|
||||||
// transform errors
|
// transform errors
|
||||||
[ErrorCodes.X_V_IF_NO_EXPRESSION]: `v-if/v-else-if is missing expression.`,
|
[ErrorCodes.X_V_IF_NO_EXPRESSION]: `v-if/v-else-if is missing expression.`,
|
||||||
|
|
|
@ -763,13 +763,26 @@ function backTrack(index: number, c: number) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const specialTemplateDir = new Set(['if', 'else', 'else-if', 'for', 'slot'])
|
const specialTemplateDir = new Set(['if', 'else', 'else-if', 'for', 'slot'])
|
||||||
function isFragmentTemplate({ tag, props }: ElementNode): boolean {
|
function isFragmentTemplate({ tag, props, loc }: ElementNode): boolean {
|
||||||
if (tag === 'template') {
|
if (tag === 'template') {
|
||||||
for (let i = 0; i < props.length; i++) {
|
for (let i = 0; i < props.length; i++) {
|
||||||
if (
|
if (
|
||||||
props[i].type === NodeTypes.DIRECTIVE &&
|
props[i].type === NodeTypes.DIRECTIVE &&
|
||||||
specialTemplateDir.has((props[i] as DirectiveNode).name)
|
specialTemplateDir.has((props[i] as DirectiveNode).name)
|
||||||
) {
|
) {
|
||||||
|
if (
|
||||||
|
stack[0] &&
|
||||||
|
'tagType' in stack[0] &&
|
||||||
|
!isComponent(stack[0]) &&
|
||||||
|
props.find(p => p.name === 'slot')
|
||||||
|
) {
|
||||||
|
currentOptions.onError(
|
||||||
|
createCompilerError(
|
||||||
|
ErrorCodes.X_SLOT_TEMPLATE_NOT_ROOT,
|
||||||
|
getLoc(loc.start.offset, loc.end.offset),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ export function createDOMCompilerError(
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum DOMErrorCodes {
|
export enum DOMErrorCodes {
|
||||||
X_V_HTML_NO_EXPRESSION = 53 /* ErrorCodes.__EXTEND_POINT__ */,
|
X_V_HTML_NO_EXPRESSION = 54 /* ErrorCodes.__EXTEND_POINT__ */,
|
||||||
X_V_HTML_WITH_CHILDREN,
|
X_V_HTML_WITH_CHILDREN,
|
||||||
X_V_TEXT_NO_EXPRESSION,
|
X_V_TEXT_NO_EXPRESSION,
|
||||||
X_V_TEXT_WITH_CHILDREN,
|
X_V_TEXT_WITH_CHILDREN,
|
||||||
|
|
Loading…
Reference in New Issue