feat(compiler): render <slot/> as block fragments
This commit is contained in:
@@ -274,16 +274,13 @@ describe('compiler: transform', () => {
|
||||
|
||||
test('single <slot/>', () => {
|
||||
const ast = transformWithCodegen(`<slot/>`)
|
||||
expect(ast.codegenNode).toMatchObject(
|
||||
createBlockMatcher([
|
||||
`_${FRAGMENT}`,
|
||||
`null`,
|
||||
{
|
||||
type: NodeTypes.JS_CALL_EXPRESSION,
|
||||
callee: `_${RENDER_SLOT}`
|
||||
}
|
||||
])
|
||||
)
|
||||
expect(ast.codegenNode).toMatchObject({
|
||||
codegenNode: {
|
||||
type: NodeTypes.JS_CALL_EXPRESSION,
|
||||
callee: `_${RENDER_SLOT}`,
|
||||
arguments: ['$slots.default']
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
test('single element', () => {
|
||||
|
||||
@@ -112,7 +112,21 @@ return function render() {
|
||||
const { renderList: _renderList, openBlock: _openBlock, createBlock: _createBlock, Fragment: _Fragment, renderSlot: _renderSlot } = _Vue
|
||||
|
||||
return (_openBlock(), _createBlock(_Fragment, null, _renderList(items, (item) => {
|
||||
return (_openBlock(), _createBlock(_Fragment, null, _renderSlot($slots.default)))
|
||||
return _renderSlot($slots.default)
|
||||
}), 128 /* UNKEYED_FRAGMENT */))
|
||||
}
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`compiler: v-for codegen v-for on <slot/> 1`] = `
|
||||
"const _Vue = Vue
|
||||
|
||||
return function render() {
|
||||
with (this) {
|
||||
const { renderList: _renderList, openBlock: _openBlock, createBlock: _createBlock, Fragment: _Fragment, renderSlot: _renderSlot } = _Vue
|
||||
|
||||
return (_openBlock(), _createBlock(_Fragment, null, _renderList(items, (item) => {
|
||||
return _renderSlot($slots.default)
|
||||
}), 128 /* UNKEYED_FRAGMENT */))
|
||||
}
|
||||
}"
|
||||
|
||||
@@ -37,10 +37,10 @@ exports[`compiler: v-if codegen template v-if w/ single <slot/> child 1`] = `
|
||||
|
||||
return function render() {
|
||||
with (this) {
|
||||
const { openBlock: _openBlock, renderSlot: _renderSlot, Fragment: _Fragment, createBlock: _createBlock, Empty: _Empty } = _Vue
|
||||
const { openBlock: _openBlock, renderSlot: _renderSlot, createBlock: _createBlock, Empty: _Empty } = _Vue
|
||||
|
||||
return (_openBlock(), ok
|
||||
? _createBlock(_Fragment, { key: 0 }, _renderSlot($slots.default))
|
||||
? _renderSlot($slots.default, { key: 0 })
|
||||
: _createBlock(_Empty))
|
||||
}
|
||||
}"
|
||||
|
||||
@@ -567,7 +567,8 @@ describe('compiler: v-for', () => {
|
||||
describe('codegen', () => {
|
||||
function assertSharedCodegen(
|
||||
node: SequenceExpression,
|
||||
keyed: boolean = false
|
||||
keyed: boolean = false,
|
||||
customReturn: boolean = false
|
||||
) {
|
||||
expect(node).toMatchObject({
|
||||
type: NodeTypes.JS_SEQUENCE_EXPRESSION,
|
||||
@@ -589,19 +590,21 @@ describe('compiler: v-for', () => {
|
||||
{}, // to be asserted by each test
|
||||
{
|
||||
type: NodeTypes.JS_FUNCTION_EXPRESSION,
|
||||
returns: {
|
||||
type: NodeTypes.JS_SEQUENCE_EXPRESSION,
|
||||
expressions: [
|
||||
{
|
||||
type: NodeTypes.JS_CALL_EXPRESSION,
|
||||
callee: `_${OPEN_BLOCK}`
|
||||
},
|
||||
{
|
||||
type: NodeTypes.JS_CALL_EXPRESSION,
|
||||
callee: `_${CREATE_BLOCK}`
|
||||
returns: customReturn
|
||||
? {}
|
||||
: {
|
||||
type: NodeTypes.JS_SEQUENCE_EXPRESSION,
|
||||
expressions: [
|
||||
{
|
||||
type: NodeTypes.JS_CALL_EXPRESSION,
|
||||
callee: `_${OPEN_BLOCK}`
|
||||
},
|
||||
{
|
||||
type: NodeTypes.JS_CALL_EXPRESSION,
|
||||
callee: `_${CREATE_BLOCK}`
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -621,7 +624,10 @@ describe('compiler: v-for', () => {
|
||||
return {
|
||||
source: renderListArgs[0] as SimpleExpressionNode,
|
||||
params: (renderListArgs[1] as any).params,
|
||||
blockArgs: (renderListArgs[1] as any).returns.expressions[1].arguments
|
||||
returns: (renderListArgs[1] as any).returns,
|
||||
blockArgs: customReturn
|
||||
? null
|
||||
: (renderListArgs[1] as any).returns.expressions[1].arguments
|
||||
}
|
||||
}
|
||||
|
||||
@@ -715,17 +721,33 @@ describe('compiler: v-for', () => {
|
||||
} = parseWithForTransform(
|
||||
'<template v-for="item in items"><slot/></template>'
|
||||
)
|
||||
expect(assertSharedCodegen(codegenNode)).toMatchObject({
|
||||
expect(
|
||||
assertSharedCodegen(codegenNode, false, true /* custom return */)
|
||||
).toMatchObject({
|
||||
source: { content: `items` },
|
||||
params: [{ content: `item` }],
|
||||
blockArgs: [
|
||||
`_${FRAGMENT}`,
|
||||
`null`,
|
||||
{
|
||||
type: NodeTypes.JS_CALL_EXPRESSION,
|
||||
callee: `_${RENDER_SLOT}`
|
||||
}
|
||||
]
|
||||
returns: {
|
||||
type: NodeTypes.JS_CALL_EXPRESSION,
|
||||
callee: `_${RENDER_SLOT}`
|
||||
}
|
||||
})
|
||||
expect(generate(root).code).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test('v-for on <slot/>', () => {
|
||||
const {
|
||||
root,
|
||||
node: { codegenNode }
|
||||
} = parseWithForTransform('<slot v-for="item in items"></slot>')
|
||||
expect(
|
||||
assertSharedCodegen(codegenNode, false, true /* custom return */)
|
||||
).toMatchObject({
|
||||
source: { content: `items` },
|
||||
params: [{ content: `item` }],
|
||||
returns: {
|
||||
type: NodeTypes.JS_CALL_EXPRESSION,
|
||||
callee: `_${RENDER_SLOT}`
|
||||
}
|
||||
})
|
||||
expect(generate(root).code).toMatchSnapshot()
|
||||
})
|
||||
@@ -794,7 +816,7 @@ describe('compiler: v-for', () => {
|
||||
// should optimize v-if + v-for into a single Fragment block
|
||||
arguments: [
|
||||
`_${FRAGMENT}`,
|
||||
`{ key: 0 }`,
|
||||
createObjectMatcher({ key: `[0]` }),
|
||||
{
|
||||
type: NodeTypes.JS_CALL_EXPRESSION,
|
||||
callee: `_${RENDER_LIST}`,
|
||||
|
||||
@@ -316,7 +316,10 @@ describe('compiler: v-if', () => {
|
||||
assertSharedCodegen(codegenNode)
|
||||
const branch1 = (codegenNode.expressions[1] as ConditionalExpression)
|
||||
.consequent as CallExpression
|
||||
expect(branch1.arguments).toMatchObject([`"div"`, `{ key: 0 }`])
|
||||
expect(branch1.arguments).toMatchObject([
|
||||
`"div"`,
|
||||
createObjectMatcher({ key: `[0]` })
|
||||
])
|
||||
const branch2 = (codegenNode.expressions[1] as ConditionalExpression)
|
||||
.alternate as CallExpression
|
||||
expect(branch2.arguments).toMatchObject([`_${EMPTY}`])
|
||||
@@ -333,7 +336,7 @@ describe('compiler: v-if', () => {
|
||||
.consequent as CallExpression
|
||||
expect(branch1.arguments).toMatchObject([
|
||||
`_${FRAGMENT}`,
|
||||
`{ key: 0 }`,
|
||||
createObjectMatcher({ key: `[0]` }),
|
||||
[
|
||||
{ type: NodeTypes.ELEMENT, tag: 'div' },
|
||||
{ type: NodeTypes.TEXT, content: `hello` },
|
||||
@@ -351,17 +354,14 @@ describe('compiler: v-if', () => {
|
||||
root,
|
||||
node: { codegenNode }
|
||||
} = parseWithIfTransform(`<template v-if="ok"><slot/></template>`)
|
||||
assertSharedCodegen(codegenNode)
|
||||
// assertSharedCodegen(codegenNode)
|
||||
const branch1 = (codegenNode.expressions[1] as ConditionalExpression)
|
||||
.consequent as CallExpression
|
||||
expect(branch1.arguments).toMatchObject([
|
||||
`_${FRAGMENT}`,
|
||||
`{ key: 0 }`,
|
||||
{
|
||||
type: NodeTypes.JS_CALL_EXPRESSION,
|
||||
callee: `_${RENDER_SLOT}`
|
||||
}
|
||||
])
|
||||
expect(branch1).toMatchObject({
|
||||
type: NodeTypes.JS_CALL_EXPRESSION,
|
||||
callee: `_${RENDER_SLOT}`,
|
||||
arguments: ['$slots.default', createObjectMatcher({ key: `[0]` })]
|
||||
})
|
||||
expect(generate(root).code).toMatchSnapshot()
|
||||
})
|
||||
|
||||
@@ -373,10 +373,16 @@ describe('compiler: v-if', () => {
|
||||
assertSharedCodegen(codegenNode)
|
||||
const branch1 = (codegenNode.expressions[1] as ConditionalExpression)
|
||||
.consequent as CallExpression
|
||||
expect(branch1.arguments).toMatchObject([`"div"`, `{ key: 0 }`])
|
||||
expect(branch1.arguments).toMatchObject([
|
||||
`"div"`,
|
||||
createObjectMatcher({ key: `[0]` })
|
||||
])
|
||||
const branch2 = (codegenNode.expressions[1] as ConditionalExpression)
|
||||
.alternate as CallExpression
|
||||
expect(branch2.arguments).toMatchObject([`"p"`, `{ key: 1 }`])
|
||||
expect(branch2.arguments).toMatchObject([
|
||||
`"p"`,
|
||||
createObjectMatcher({ key: `[1]` })
|
||||
])
|
||||
expect(generate(root).code).toMatchSnapshot()
|
||||
})
|
||||
|
||||
@@ -388,12 +394,15 @@ describe('compiler: v-if', () => {
|
||||
assertSharedCodegen(codegenNode, 1)
|
||||
const branch1 = (codegenNode.expressions[1] as ConditionalExpression)
|
||||
.consequent as CallExpression
|
||||
expect(branch1.arguments).toMatchObject([`"div"`, `{ key: 0 }`])
|
||||
expect(branch1.arguments).toMatchObject([
|
||||
`"div"`,
|
||||
createObjectMatcher({ key: `[0]` })
|
||||
])
|
||||
const branch2 = (codegenNode.expressions[1] as ConditionalExpression)
|
||||
.alternate as ConditionalExpression
|
||||
expect((branch2.consequent as CallExpression).arguments).toMatchObject([
|
||||
`"p"`,
|
||||
`{ key: 1 }`
|
||||
createObjectMatcher({ key: `[1]` })
|
||||
])
|
||||
expect(generate(root).code).toMatchSnapshot()
|
||||
})
|
||||
@@ -408,16 +417,19 @@ describe('compiler: v-if', () => {
|
||||
assertSharedCodegen(codegenNode, 1)
|
||||
const branch1 = (codegenNode.expressions[1] as ConditionalExpression)
|
||||
.consequent as CallExpression
|
||||
expect(branch1.arguments).toMatchObject([`"div"`, `{ key: 0 }`])
|
||||
expect(branch1.arguments).toMatchObject([
|
||||
`"div"`,
|
||||
createObjectMatcher({ key: `[0]` })
|
||||
])
|
||||
const branch2 = (codegenNode.expressions[1] as ConditionalExpression)
|
||||
.alternate as ConditionalExpression
|
||||
expect((branch2.consequent as CallExpression).arguments).toMatchObject([
|
||||
`"p"`,
|
||||
`{ key: 1 }`
|
||||
createObjectMatcher({ key: `[1]` })
|
||||
])
|
||||
expect((branch2.alternate as CallExpression).arguments).toMatchObject([
|
||||
`_${FRAGMENT}`,
|
||||
`{ key: 2 }`,
|
||||
createObjectMatcher({ key: `[2]` }),
|
||||
[
|
||||
{
|
||||
type: NodeTypes.TEXT,
|
||||
@@ -437,7 +449,7 @@ describe('compiler: v-if', () => {
|
||||
expect(branch1.arguments[1]).toMatchObject({
|
||||
type: NodeTypes.JS_CALL_EXPRESSION,
|
||||
callee: `_${MERGE_PROPS}`,
|
||||
arguments: [`{ key: 0 }`, { content: `obj` }]
|
||||
arguments: [createObjectMatcher({ key: `[0]` }), { content: `obj` }]
|
||||
})
|
||||
})
|
||||
|
||||
@@ -470,7 +482,7 @@ describe('compiler: v-if', () => {
|
||||
type: NodeTypes.JS_CALL_EXPRESSION,
|
||||
callee: `_${MERGE_PROPS}`,
|
||||
arguments: [
|
||||
`{ key: 0 }`,
|
||||
createObjectMatcher({ key: `[0]` }),
|
||||
{ content: `obj` },
|
||||
createObjectMatcher({
|
||||
id: 'foo'
|
||||
@@ -487,9 +499,11 @@ describe('compiler: v-if', () => {
|
||||
.consequent as CallExpression
|
||||
expect(branch1.callee).toBe(`_${APPLY_DIRECTIVES}`)
|
||||
const realBranch = branch1.arguments[0] as CallExpression
|
||||
expect(realBranch.arguments[1]).toBe(`{ key: 0 }`)
|
||||
expect(realBranch.arguments[1]).toMatchObject(
|
||||
createObjectMatcher({ key: `[0]` })
|
||||
)
|
||||
})
|
||||
|
||||
test('with comments', () => {})
|
||||
test.todo('with comments')
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user