feat(compiler-core/v-slot): only force dynamic slots when referencing scope vars

This feature is only applied with prefixIdentifiers: true.
This commit is contained in:
Evan You
2019-10-16 15:30:21 -04:00
parent 5e97643c85
commit d69db0b2fd
4 changed files with 123 additions and 12 deletions

View File

@@ -25,8 +25,8 @@ function parseWithVModel(template: string, options: CompilerOptions = {}) {
nodeTransforms: [
transformFor,
transformExpression,
trackSlotScopes,
transformElement
transformElement,
trackSlotScopes
],
directiveTransforms: {
...options.directiveTransforms,

View File

@@ -7,7 +7,8 @@ import {
NodeTypes,
ErrorCodes,
ForNode,
CallExpression
CallExpression,
ComponentNode
} from '../../src'
import { transformElement } from '../../src/transforms/transformElement'
import { transformOn } from '../../src/transforms/vOn'
@@ -32,8 +33,8 @@ function parseWithSlots(template: string, options: CompilerOptions = {}) {
...(options.prefixIdentifiers
? [trackVForSlotScopes, transformExpression]
: []),
trackSlotScopes,
transformElement
transformElement,
trackSlotScopes
],
directiveTransforms: {
on: transformOn,
@@ -347,7 +348,60 @@ describe('compiler: transform component slots', () => {
const div = ((root.children[0] as ForNode).children[0] as ElementNode)
.codegenNode as any
const comp = div.arguments[2][0]
expect(comp.codegenNode.arguments[3]).toMatch(PatchFlags.DYNAMIC_SLOTS + '')
expect(comp.codegenNode.arguments[3]).toBe(
genFlagText(PatchFlags.DYNAMIC_SLOTS)
)
})
test('should only force dynamic slots when actually using scope vars w/ prefixIdentifiers: true', () => {
function assertDynamicSlots(template: string, shouldForce: boolean) {
const { root } = parseWithSlots(template, { prefixIdentifiers: true })
let flag: any
if (root.children[0].type === NodeTypes.FOR) {
const div = (root.children[0].children[0] as ElementNode)
.codegenNode as any
const comp = div.arguments[2][0]
flag = comp.codegenNode.arguments[3]
} else {
const innerComp = (root.children[0] as ComponentNode)
.children[0] as ComponentNode
flag = innerComp.codegenNode!.arguments[3]
}
if (shouldForce) {
expect(flag).toBe(genFlagText(PatchFlags.DYNAMIC_SLOTS))
} else {
expect(flag).toBeUndefined()
}
}
assertDynamicSlots(
`<div v-for="i in list">
<Comp v-slot="bar">foo</Comp>
</div>`,
false
)
assertDynamicSlots(
`<div v-for="i in list">
<Comp v-slot="bar">{{ i }}</Comp>
</div>`,
true
)
// reference the component's own slot variable should not force dynamic slots
assertDynamicSlots(
`<Comp v-slot="foo">
<Comp v-slot="bar">{{ bar }}</Comp>
</Comp>`,
false
)
assertDynamicSlots(
`<Comp v-slot="foo">
<Comp v-slot="bar">{{ foo }}</Comp>
</Comp>`,
true
)
})
test('named slot with v-if', () => {