fix(compiler-core): support static slot names containing dots for 2.x compat

close #1241
This commit is contained in:
Evan You 2020-06-12 16:09:27 -04:00
parent 0d26413433
commit 825ec1500f
2 changed files with 46 additions and 8 deletions

View File

@ -1401,6 +1401,36 @@ describe('compiler: parse', () => {
}) })
}) })
// #1241 special case for 2.x compat
test('v-slot arg containing dots', () => {
const ast = baseParse('<Comp v-slot:foo.bar="{ a }" />')
const directive = (ast.children[0] as ElementNode).props[0]
expect(directive).toMatchObject({
type: NodeTypes.DIRECTIVE,
name: 'slot',
arg: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: 'foo.bar',
isStatic: true,
isConstant: true,
loc: {
source: 'foo.bar',
start: {
column: 14,
line: 1,
offset: 13
},
end: {
column: 21,
line: 1,
offset: 20
}
}
}
})
})
test('v-pre', () => { test('v-pre', () => {
const ast = baseParse( const ast = baseParse(
`<div v-pre :id="foo"><Comp/>{{ bar }}</div>\n` + `<div v-pre :id="foo"><Comp/>{{ bar }}</div>\n` +

View File

@ -603,14 +603,23 @@ function parseAttribute(
name name
)! )!
const dirName =
match[1] ||
(startsWith(name, ':') ? 'bind' : startsWith(name, '@') ? 'on' : 'slot')
let arg: ExpressionNode | undefined let arg: ExpressionNode | undefined
if (match[2]) { if (match[2]) {
const isSlot = dirName === 'slot'
const startOffset = name.indexOf(match[2]) const startOffset = name.indexOf(match[2])
const loc = getSelection( const loc = getSelection(
context, context,
getNewPosition(context, start, startOffset), getNewPosition(context, start, startOffset),
getNewPosition(context, start, startOffset + match[2].length) getNewPosition(
context,
start,
startOffset + match[2].length + ((isSlot && match[3]) || '').length
)
) )
let content = match[2] let content = match[2]
let isStatic = true let isStatic = true
@ -626,6 +635,11 @@ function parseAttribute(
} }
content = content.substr(1, content.length - 2) content = content.substr(1, content.length - 2)
} else if (isSlot) {
// #1241 special case for v-slot: vuetify relies extensively on slot
// names containing dots. v-slot doesn't have any modifiers and Vue 2.x
// supports such usage so we are keeping it consistent with 2.x.
content += match[3] || ''
} }
arg = { arg = {
@ -647,13 +661,7 @@ function parseAttribute(
return { return {
type: NodeTypes.DIRECTIVE, type: NodeTypes.DIRECTIVE,
name: name: dirName,
match[1] ||
(startsWith(name, ':')
? 'bind'
: startsWith(name, '@')
? 'on'
: 'slot'),
exp: value && { exp: value && {
type: NodeTypes.SIMPLE_EXPRESSION, type: NodeTypes.SIMPLE_EXPRESSION,
content: value.content, content: value.content,