feat(compiler): support keep-alive in templates

This commit is contained in:
Evan You
2019-11-05 10:26:36 -05:00
parent a5f1387d78
commit 98e9b769e6
5 changed files with 136 additions and 82 deletions

View File

@@ -8,7 +8,9 @@ import {
TO_HANDLERS,
helperNameMap,
PORTAL,
RESOLVE_DYNAMIC_COMPONENT
RESOLVE_DYNAMIC_COMPONENT,
SUSPENSE,
KEEP_ALIVE
} from '../../src/runtimeHelpers'
import {
CallExpression,
@@ -265,50 +267,97 @@ describe('compiler: element transform', () => {
])
})
test('should handle <portal> element', () => {
const { node } = parseWithElementTransform(
`<portal target="#foo"><span /></portal>`
)
expect(node.callee).toBe(CREATE_VNODE)
expect(node.arguments).toMatchObject([
PORTAL,
createObjectMatcher({
target: '#foo'
}),
[
{
type: NodeTypes.ELEMENT,
tag: 'span',
codegenNode: {
callee: CREATE_VNODE,
arguments: [`"span"`]
test('should handle <Portal> with normal children', () => {
function assert(tag: string) {
const { root, node } = parseWithElementTransform(
`<${tag} target="#foo"><span /></${tag}>`
)
expect(root.components.length).toBe(0)
expect(root.helpers).toContain(PORTAL)
expect(node.callee).toBe(CREATE_VNODE)
expect(node.arguments).toMatchObject([
PORTAL,
createObjectMatcher({
target: '#foo'
}),
[
{
type: NodeTypes.ELEMENT,
tag: 'span',
codegenNode: {
callee: CREATE_VNODE,
arguments: [`"span"`]
}
}
}
]
])
]
])
}
assert(`portal`)
assert(`Portal`)
})
test('should handle <Portal> element', () => {
const { node } = parseWithElementTransform(
`<Portal target="#foo"><span /></Portal>`
test('should handle <Suspense>', () => {
function assert(tag: string, content: string, hasFallback?: boolean) {
const { root, node } = parseWithElementTransform(
`<${tag}>${content}</${tag}>`
)
expect(root.components.length).toBe(0)
expect(root.helpers).toContain(SUSPENSE)
expect(node.callee).toBe(CREATE_VNODE)
expect(node.arguments).toMatchObject([
SUSPENSE,
`null`,
hasFallback
? createObjectMatcher({
default: {
type: NodeTypes.JS_FUNCTION_EXPRESSION
},
fallback: {
type: NodeTypes.JS_FUNCTION_EXPRESSION
},
_compiled: `[true]`
})
: createObjectMatcher({
default: {
type: NodeTypes.JS_FUNCTION_EXPRESSION
},
_compiled: `[true]`
})
])
}
assert(`suspense`, `foo`)
assert(`suspense`, `<template #default>foo</template>`)
assert(
`suspense`,
`<template #default>foo</template><template #fallback>fallback</template>`,
true
)
expect(node.callee).toBe(CREATE_VNODE)
expect(node.arguments).toMatchObject([
PORTAL,
createObjectMatcher({
target: '#foo'
}),
[
{
type: NodeTypes.ELEMENT,
tag: 'span',
codegenNode: {
callee: CREATE_VNODE,
arguments: [`"span"`]
}
}
]
])
})
test('should handle <KeepAlive>', () => {
function assert(tag: string) {
const { root, node } = parseWithElementTransform(
`<${tag}><span /></${tag}>`
)
expect(root.components.length).toBe(0)
expect(root.helpers).toContain(KEEP_ALIVE)
expect(node.callee).toBe(CREATE_VNODE)
expect(node.arguments).toMatchObject([
KEEP_ALIVE,
`null`,
createObjectMatcher({
default: {
type: NodeTypes.JS_FUNCTION_EXPRESSION
},
_compiled: `[true]`
})
])
}
assert(`keep-alive`)
assert(`KeepAlive`)
})
test('error on v-bind with no argument', () => {