perf(compiler-core): treat v-for with constant exp as a stable fragment (#1394)
This commit is contained in:
@@ -102,6 +102,15 @@ return function render(_ctx, _cache) {
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`compiler: codegen forNode with constant expression 1`] = `
|
||||
"
|
||||
return function render(_ctx, _cache) {
|
||||
with (_ctx) {
|
||||
return (_openBlock(), _createBlock(_Fragment, null, _renderList(), 64 /* STABLE_FRAGMENT */))
|
||||
}
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`compiler: codegen function mode preamble 1`] = `
|
||||
"const _Vue = Vue
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ import {
|
||||
FRAGMENT,
|
||||
RENDER_LIST
|
||||
} from '../src/runtimeHelpers'
|
||||
import { createElementWithCodegen } from './testUtils'
|
||||
import { createElementWithCodegen, genFlagText } from './testUtils'
|
||||
import { PatchFlags } from '@vue/shared'
|
||||
|
||||
function createRoot(options: Partial<RootNode> = {}): RootNode {
|
||||
@@ -283,7 +283,7 @@ describe('compiler: codegen', () => {
|
||||
type: NodeTypes.VNODE_CALL,
|
||||
tag: FRAGMENT,
|
||||
isBlock: true,
|
||||
isForBlock: true,
|
||||
disableTracking: true,
|
||||
props: undefined,
|
||||
children: createCallExpression(RENDER_LIST),
|
||||
patchFlag: '1',
|
||||
@@ -298,6 +298,37 @@ describe('compiler: codegen', () => {
|
||||
expect(code).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test('forNode with constant expression', () => {
|
||||
const { code } = generate(
|
||||
createRoot({
|
||||
codegenNode: {
|
||||
type: NodeTypes.FOR,
|
||||
loc: locStub,
|
||||
source: createSimpleExpression('1 + 2', false, locStub, true),
|
||||
valueAlias: undefined,
|
||||
keyAlias: undefined,
|
||||
objectIndexAlias: undefined,
|
||||
children: [],
|
||||
parseResult: {} as any,
|
||||
codegenNode: {
|
||||
type: NodeTypes.VNODE_CALL,
|
||||
tag: FRAGMENT,
|
||||
isBlock: true,
|
||||
disableTracking: false,
|
||||
props: undefined,
|
||||
children: createCallExpression(RENDER_LIST),
|
||||
patchFlag: genFlagText(PatchFlags.STABLE_FRAGMENT),
|
||||
dynamicProps: undefined,
|
||||
directives: undefined,
|
||||
loc: locStub
|
||||
} as ForCodegenNode
|
||||
}
|
||||
})
|
||||
)
|
||||
expect(code).toMatch(`openBlock()`)
|
||||
expect(code).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test('Element (callExpression + objectExpression + TemplateChildNode[])', () => {
|
||||
const { code } = generate(
|
||||
createRoot({
|
||||
|
||||
@@ -62,7 +62,7 @@ export function createElementWithCodegen(
|
||||
dynamicProps,
|
||||
directives: undefined,
|
||||
isBlock: false,
|
||||
isForBlock: false,
|
||||
disableTracking: false,
|
||||
loc: locStub
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,6 +150,20 @@ return function render(_ctx, _cache) {
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`compiler: v-for codegen v-for with constant expression 1`] = `
|
||||
"const _Vue = Vue
|
||||
|
||||
return function render(_ctx, _cache) {
|
||||
with (_ctx) {
|
||||
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, toDisplayString: _toDisplayString, createVNode: _createVNode } = _Vue
|
||||
|
||||
return (_openBlock(), _createBlock(_Fragment, null, _renderList(10, (item) => {
|
||||
return _createVNode(\\"p\\", null, _toDisplayString(item), 1 /* TEXT */)
|
||||
}), 64 /* STABLE_FRAGMENT */))
|
||||
}
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`compiler: v-for codegen v-if + v-for 1`] = `
|
||||
"const _Vue = Vue
|
||||
|
||||
|
||||
@@ -560,15 +560,18 @@ describe('compiler: v-for', () => {
|
||||
function assertSharedCodegen(
|
||||
node: ForCodegenNode,
|
||||
keyed: boolean = false,
|
||||
customReturn: boolean = false
|
||||
customReturn: boolean = false,
|
||||
disableTracking: boolean = true
|
||||
) {
|
||||
expect(node).toMatchObject({
|
||||
type: NodeTypes.VNODE_CALL,
|
||||
tag: FRAGMENT,
|
||||
isForBlock: true,
|
||||
patchFlag: keyed
|
||||
? genFlagText(PatchFlags.KEYED_FRAGMENT)
|
||||
: genFlagText(PatchFlags.UNKEYED_FRAGMENT),
|
||||
disableTracking,
|
||||
patchFlag: !disableTracking
|
||||
? genFlagText(PatchFlags.STABLE_FRAGMENT)
|
||||
: keyed
|
||||
? genFlagText(PatchFlags.KEYED_FRAGMENT)
|
||||
: genFlagText(PatchFlags.UNKEYED_FRAGMENT),
|
||||
children: {
|
||||
type: NodeTypes.JS_CALL_EXPRESSION,
|
||||
callee: RENDER_LIST,
|
||||
@@ -580,7 +583,7 @@ describe('compiler: v-for', () => {
|
||||
? {}
|
||||
: {
|
||||
type: NodeTypes.VNODE_CALL,
|
||||
isBlock: true
|
||||
isBlock: disableTracking
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -658,6 +661,43 @@ describe('compiler: v-for', () => {
|
||||
expect(generate(root).code).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test('v-for with constant expression', () => {
|
||||
const {
|
||||
root,
|
||||
node: { codegenNode }
|
||||
} = parseWithForTransform('<p v-for="item in 10">{{item}}</p>', {
|
||||
prefixIdentifiers: true
|
||||
})
|
||||
|
||||
expect(
|
||||
assertSharedCodegen(
|
||||
codegenNode,
|
||||
false /* keyed */,
|
||||
false /* customReturn */,
|
||||
false /* disableTracking */
|
||||
)
|
||||
).toMatchObject({
|
||||
source: { content: `10`, isConstant: true },
|
||||
params: [{ content: `item` }],
|
||||
innerVNodeCall: {
|
||||
tag: `"p"`,
|
||||
props: undefined,
|
||||
isBlock: false,
|
||||
children: {
|
||||
type: NodeTypes.INTERPOLATION,
|
||||
content: {
|
||||
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||
content: 'item',
|
||||
isStatic: false,
|
||||
isConstant: false
|
||||
}
|
||||
},
|
||||
patchFlag: genFlagText(PatchFlags.TEXT)
|
||||
}
|
||||
})
|
||||
expect(generate(root).code).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test('template v-for', () => {
|
||||
const {
|
||||
root,
|
||||
@@ -777,7 +817,7 @@ describe('compiler: v-for', () => {
|
||||
key: `[0]`
|
||||
}),
|
||||
isBlock: true,
|
||||
isForBlock: true,
|
||||
disableTracking: true,
|
||||
patchFlag: genFlagText(PatchFlags.UNKEYED_FRAGMENT),
|
||||
children: {
|
||||
type: NodeTypes.JS_CALL_EXPRESSION,
|
||||
|
||||
Reference in New Issue
Block a user