parent
6d10a6c772
commit
ade07c64a1
@ -346,18 +346,26 @@ describe('compiler: element transform', () => {
|
|||||||
|
|
||||||
test('should handle <KeepAlive>', () => {
|
test('should handle <KeepAlive>', () => {
|
||||||
function assert(tag: string) {
|
function assert(tag: string) {
|
||||||
const { root, node } = parseWithElementTransform(
|
const root = parse(`<div><${tag}><span /></${tag}></div>`)
|
||||||
`<${tag}><span /></${tag}>`
|
transform(root, {
|
||||||
)
|
nodeTransforms: [transformElement, transformText]
|
||||||
|
})
|
||||||
expect(root.components.length).toBe(0)
|
expect(root.components.length).toBe(0)
|
||||||
expect(root.helpers).toContain(KEEP_ALIVE)
|
expect(root.helpers).toContain(KEEP_ALIVE)
|
||||||
expect(node.callee).toBe(CREATE_VNODE)
|
const node = (root.children[0] as any).children[0].codegenNode
|
||||||
expect(node.arguments).toMatchObject([
|
expect(node.type).toBe(NodeTypes.JS_SEQUENCE_EXPRESSION)
|
||||||
KEEP_ALIVE,
|
expect(node.expressions[1]).toMatchObject({
|
||||||
`null`,
|
type: NodeTypes.JS_CALL_EXPRESSION,
|
||||||
// keep-alive should not compile content to slots
|
callee: CREATE_BLOCK, // should be forced into a block
|
||||||
[{ type: NodeTypes.ELEMENT, tag: 'span' }]
|
arguments: [
|
||||||
])
|
KEEP_ALIVE,
|
||||||
|
`null`,
|
||||||
|
// keep-alive should not compile content to slots
|
||||||
|
[{ type: NodeTypes.ELEMENT, tag: 'span' }],
|
||||||
|
// should get a dynamic slots flag to force updates
|
||||||
|
genFlagText(PatchFlags.DYNAMIC_SLOTS)
|
||||||
|
]
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(`keep-alive`)
|
assert(`keep-alive`)
|
||||||
|
@ -67,7 +67,7 @@ export const transformElement: NodeTransform = (node, context) => {
|
|||||||
// updates inside get proper isSVG flag at runtime. (#639, #643)
|
// updates inside get proper isSVG flag at runtime. (#639, #643)
|
||||||
// This is technically web-specific, but splitting the logic out of core
|
// This is technically web-specific, but splitting the logic out of core
|
||||||
// leads to too much unnecessary complexity.
|
// leads to too much unnecessary complexity.
|
||||||
const shouldUseBlock =
|
let shouldUseBlock =
|
||||||
!isComponent && (tag === 'svg' || tag === 'foreignObject')
|
!isComponent && (tag === 'svg' || tag === 'foreignObject')
|
||||||
|
|
||||||
const nodeType = isComponent
|
const nodeType = isComponent
|
||||||
@ -101,21 +101,35 @@ export const transformElement: NodeTransform = (node, context) => {
|
|||||||
args.push(`null`)
|
args.push(`null`)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (__DEV__ && nodeType === KEEP_ALIVE && node.children.length > 1) {
|
if (nodeType === KEEP_ALIVE) {
|
||||||
context.onError(
|
// Although a built-in component, we compile KeepAlive with raw children
|
||||||
createCompilerError(ErrorCodes.X_KEEP_ALIVE_INVALID_CHILDREN, {
|
// instead of slot functions so that it can be used inside Transition
|
||||||
start: node.children[0].loc.start,
|
// or other Transition-wrapping HOCs.
|
||||||
end: node.children[node.children.length - 1].loc.end,
|
// To ensure correct updates with block optimizations, we need to:
|
||||||
source: ''
|
// 1. Force keep-alive into a block. This avoids its children being
|
||||||
})
|
// collected by a parent block.
|
||||||
)
|
shouldUseBlock = true
|
||||||
|
// 2. Force keep-alive to always be updated, since it uses raw children.
|
||||||
|
patchFlag |= PatchFlags.DYNAMIC_SLOTS
|
||||||
|
if (__DEV__ && 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
|
const shouldBuildAsSlots =
|
||||||
// Portal is not a real component has dedicated handling in the renderer
|
isComponent &&
|
||||||
// KeepAlive should not track its own deps so that it can be used inside
|
// Portal is not a real component has dedicated handling in the renderer
|
||||||
// Transition
|
nodeType !== PORTAL &&
|
||||||
if (isComponent && nodeType !== PORTAL && nodeType !== KEEP_ALIVE) {
|
// explained above.
|
||||||
|
nodeType !== KEEP_ALIVE
|
||||||
|
|
||||||
|
if (shouldBuildAsSlots) {
|
||||||
const { slots, hasDynamicSlots } = buildSlots(node, context)
|
const { slots, hasDynamicSlots } = buildSlots(node, context)
|
||||||
args.push(slots)
|
args.push(slots)
|
||||||
if (hasDynamicSlots) {
|
if (hasDynamicSlots) {
|
||||||
|
Loading…
Reference in New Issue
Block a user