feat(compiler): force dynamicSlots flag when inside v-for or v-slot

This commit is contained in:
Evan You
2019-10-03 16:27:46 -04:00
parent 4dea23f79e
commit c2fc7e3347
6 changed files with 73 additions and 16 deletions

View File

@@ -159,7 +159,7 @@ return function render() {
createVNode(_component_Inner, null, {
default: ({ bar }) => [toString(foo), toString(bar), toString(_ctx.baz)],
_compiled: true
}),
}, 256 /* DYNAMIC_SLOTS */),
toString(foo),
toString(_ctx.bar),
toString(_ctx.baz)

View File

@@ -5,7 +5,8 @@ import {
generate,
ElementNode,
NodeTypes,
ErrorCodes
ErrorCodes,
ForNode
} from '../../src'
import { transformElement } from '../../src/transforms/transformElement'
import { transformOn } from '../../src/transforms/vOn'
@@ -17,15 +18,20 @@ import {
} from '../../src/transforms/vSlot'
import { CREATE_SLOTS, RENDER_LIST } from '../../src/runtimeConstants'
import { createObjectMatcher } from '../testUtils'
import { PatchFlags } from '@vue/shared'
import { PatchFlags, PatchFlagNames } from '@vue/shared'
import { transformFor } from '../../src/transforms/vFor'
import { transformIf } from '../../src/transforms/vIf'
function parseWithSlots(template: string, options: CompilerOptions = {}) {
const ast = parse(template)
transform(ast, {
nodeTransforms: [
transformIf,
transformFor,
...(options.prefixIdentifiers
? [trackVForSlotScopes, transformExpression, trackSlotScopes]
? [trackVForSlotScopes, transformExpression]
: []),
trackSlotScopes,
transformElement
],
directiveTransforms: {
@@ -36,7 +42,10 @@ function parseWithSlots(template: string, options: CompilerOptions = {}) {
})
return {
root: ast,
slots: (ast.children[0] as ElementNode).codegenNode!.arguments[2]
slots:
ast.children[0].type === NodeTypes.ELEMENT
? ast.children[0].codegenNode!.arguments[2]
: null
}
}
@@ -295,7 +304,12 @@ describe('compiler: transform component slots', () => {
}
]
}
})
}),
// nested slot should be forced dynamic, since scope variables
// are not tracked as dependencies of the slot.
`${PatchFlags.DYNAMIC_SLOTS} /* ${
PatchFlagNames[PatchFlags.DYNAMIC_SLOTS]
} */`
]
}
},
@@ -325,6 +339,18 @@ describe('compiler: transform component slots', () => {
expect(generate(root, { prefixIdentifiers: true }).code).toMatchSnapshot()
})
test('should force dynamic when inside v-for', () => {
const { root } = parseWithSlots(
`<div v-for="i in list">
<Comp v-slot="bar">foo</Comp>
</div>`
)
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 + '')
})
test('named slot with v-if', () => {
const { root, slots } = parseWithSlots(
`<Comp>