diff --git a/packages/compiler-core/__tests__/codegen.spec.ts b/packages/compiler-core/__tests__/codegen.spec.ts index 240c1949e..48a89c415 100644 --- a/packages/compiler-core/__tests__/codegen.spec.ts +++ b/packages/compiler-core/__tests__/codegen.spec.ts @@ -34,7 +34,7 @@ function createRoot(options: Partial = {}): RootNode { components: [], directives: [], hoists: [], - codegenNode: undefined, + codegenNode: createSimpleExpression(`null`, false), loc: locStub, ...options } diff --git a/packages/compiler-core/__tests__/testUtils.ts b/packages/compiler-core/__tests__/testUtils.ts index 74855d518..abffe1549 100644 --- a/packages/compiler-core/__tests__/testUtils.ts +++ b/packages/compiler-core/__tests__/testUtils.ts @@ -4,7 +4,7 @@ import { locStub, Namespaces, ElementTypes, - ElementCodegenNode + PlainElementCodegenNode } from '../src' import { CREATE_VNODE } from '../src/runtimeHelpers' import { isString, PatchFlags, PatchFlagNames, isArray } from '@vue/shared' @@ -39,7 +39,7 @@ export function createObjectMatcher(obj: any) { } export function createElementWithCodegen( - args: ElementCodegenNode['arguments'] + args: PlainElementCodegenNode['arguments'] ): ElementNode { return { type: NodeTypes.ELEMENT, diff --git a/packages/compiler-core/__tests__/transform.spec.ts b/packages/compiler-core/__tests__/transform.spec.ts index 6f778e156..d9203fe88 100644 --- a/packages/compiler-core/__tests__/transform.spec.ts +++ b/packages/compiler-core/__tests__/transform.spec.ts @@ -14,7 +14,8 @@ import { OPEN_BLOCK, CREATE_BLOCK, FRAGMENT, - RENDER_SLOT + RENDER_SLOT, + APPLY_DIRECTIVES } from '../src/runtimeHelpers' import { transformIf } from '../src/transforms/vIf' import { transformFor } from '../src/transforms/vFor' @@ -301,6 +302,28 @@ describe('compiler: transform', () => { }) }) + test('root element with custom directive', () => { + const ast = transformWithCodegen(`
`) + expect(ast.codegenNode).toMatchObject({ + type: NodeTypes.JS_SEQUENCE_EXPRESSION, + expressions: [ + { + type: NodeTypes.JS_CALL_EXPRESSION, + callee: OPEN_BLOCK + }, + { + type: NodeTypes.JS_CALL_EXPRESSION, + // should wrap applyDirectives() around createBlock() + callee: APPLY_DIRECTIVES, + arguments: [ + { callee: CREATE_BLOCK }, + { type: NodeTypes.JS_ARRAY_EXPRESSION } + ] + } + ] + }) + }) + test('single text', () => { const ast = transformWithCodegen(`hello`) expect(ast.codegenNode).toMatchObject({ diff --git a/packages/compiler-core/__tests__/transforms/__snapshots__/hoistStatic.spec.ts.snap b/packages/compiler-core/__tests__/transforms/__snapshots__/hoistStatic.spec.ts.snap index 5ca448b03..6ecefb037 100644 --- a/packages/compiler-core/__tests__/transforms/__snapshots__/hoistStatic.spec.ts.snap +++ b/packages/compiler-core/__tests__/transforms/__snapshots__/hoistStatic.spec.ts.snap @@ -11,7 +11,7 @@ const _hoisted_1 = _createVNode(\\"p\\", null, [ return function render() { with (this) { - const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue + const { createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue return (_openBlock(), _createBlock(\\"div\\", null, [ _hoisted_1 @@ -29,7 +29,7 @@ const _hoisted_2 = _createVNode(\\"div\\") return function render() { with (this) { - const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue + const { createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue return (_openBlock(), _createBlock(\\"div\\", null, [ _hoisted_1, @@ -47,7 +47,7 @@ const _hoisted_1 = _createVNode(\\"span\\", { class: \\"inline\\" }, \\"hello\\" return function render() { with (this) { - const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue + const { createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue return (_openBlock(), _createBlock(\\"div\\", null, [ _hoisted_1 @@ -64,7 +64,7 @@ const _hoisted_1 = { id: \\"foo\\" } return function render() { with (this) { - const { createVNode: _createVNode, applyDirectives: _applyDirectives, resolveDirective: _resolveDirective, openBlock: _openBlock, createBlock: _createBlock } = _Vue + const { createVNode: _createVNode, applyDirectives: _applyDirectives, resolveDirective: _resolveDirective, createBlock: _createBlock, openBlock: _openBlock } = _Vue const _directive_foo = _resolveDirective(\\"foo\\") @@ -85,7 +85,7 @@ const _hoisted_1 = { id: \\"foo\\" } return function render() { with (this) { - const { toString: _toString, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue + const { toString: _toString, createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue return (_openBlock(), _createBlock(\\"div\\", null, [ _createVNode(\\"div\\", _hoisted_1, _toString(hello), 1 /* TEXT */) @@ -102,7 +102,7 @@ const _hoisted_1 = { id: \\"foo\\" } return function render() { with (this) { - const { resolveComponent: _resolveComponent, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue + const { resolveComponent: _resolveComponent, createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue const _component_Comp = _resolveComponent(\\"Comp\\") @@ -120,7 +120,7 @@ exports[`compiler: hositStatic transform should NOT hoist components 1`] = ` return function render() { with (this) { - const { resolveComponent: _resolveComponent, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue + const { resolveComponent: _resolveComponent, createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue const _component_Comp = _resolveComponent(\\"Comp\\") @@ -136,7 +136,7 @@ exports[`compiler: hositStatic transform should NOT hoist element with dynamic p return function render() { with (this) { - const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue + const { createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue return (_openBlock(), _createBlock(\\"div\\", null, [ _createVNode(\\"div\\", { id: foo }, null, 8 /* PROPS */, [\\"id\\"]) @@ -150,7 +150,7 @@ exports[`compiler: hositStatic transform should NOT hoist root node 1`] = ` return function render() { with (this) { - const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue + const { createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue return (_openBlock(), _createBlock(\\"div\\")) } diff --git a/packages/compiler-core/__tests__/transforms/__snapshots__/optimizeText.spec.ts.snap b/packages/compiler-core/__tests__/transforms/__snapshots__/optimizeText.spec.ts.snap index a876945f3..ce5754237 100644 --- a/packages/compiler-core/__tests__/transforms/__snapshots__/optimizeText.spec.ts.snap +++ b/packages/compiler-core/__tests__/transforms/__snapshots__/optimizeText.spec.ts.snap @@ -17,7 +17,7 @@ exports[`compiler: optimize interpolation consecutive text between elements 1`] return function render() { with (this) { - const { createVNode: _createVNode, toString: _toString, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock } = _Vue + const { createVNode: _createVNode, toString: _toString, createBlock: _createBlock, Fragment: _Fragment, openBlock: _openBlock } = _Vue return (_openBlock(), _createBlock(_Fragment, null, [ _createVNode(\\"div\\"), @@ -33,7 +33,7 @@ exports[`compiler: optimize interpolation consecutive text mixed with elements 1 return function render() { with (this) { - const { createVNode: _createVNode, toString: _toString, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock } = _Vue + const { createVNode: _createVNode, toString: _toString, createBlock: _createBlock, Fragment: _Fragment, openBlock: _openBlock } = _Vue return (_openBlock(), _createBlock(_Fragment, null, [ _createVNode(\\"div\\"), diff --git a/packages/compiler-core/__tests__/transforms/__snapshots__/vFor.spec.ts.snap b/packages/compiler-core/__tests__/transforms/__snapshots__/vFor.spec.ts.snap index 02bbbcbb8..454a5f43b 100644 --- a/packages/compiler-core/__tests__/transforms/__snapshots__/vFor.spec.ts.snap +++ b/packages/compiler-core/__tests__/transforms/__snapshots__/vFor.spec.ts.snap @@ -132,6 +132,24 @@ return function render() { }" `; +exports[`compiler: v-for codegen v-for on element with custom directive 1`] = ` +"const _Vue = Vue + +return function render() { + with (this) { + const { renderList: _renderList, openBlock: _openBlock, createBlock: _createBlock, Fragment: _Fragment, createVNode: _createVNode, applyDirectives: _applyDirectives, resolveDirective: _resolveDirective } = _Vue + + const _directive_foo = _resolveDirective(\\"foo\\") + + return (_openBlock(), _createBlock(_Fragment, null, _renderList(list, (i) => { + return (_openBlock(), _applyDirectives(_createBlock(\\"div\\", null, null, 32 /* NEED_PATCH */), [ + [_directive_foo] + ])) + }), 128 /* UNKEYED_FRAGMENT */)) + } +}" +`; + exports[`compiler: v-for codegen v-if + v-for 1`] = ` "const _Vue = Vue diff --git a/packages/compiler-core/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap b/packages/compiler-core/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap index 8bbb14f28..266e2f6ff 100644 --- a/packages/compiler-core/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap +++ b/packages/compiler-core/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`compiler: transform component slots dynamically named slots 1`] = ` -"const { toString, resolveComponent, createVNode, openBlock, createBlock } = Vue +"const { toString, resolveComponent, createVNode, createBlock, openBlock } = Vue return function render() { const _ctx = this @@ -16,7 +16,7 @@ return function render() { `; exports[`compiler: transform component slots explicit default slot 1`] = ` -"const { toString, resolveComponent, createVNode, openBlock, createBlock } = Vue +"const { toString, resolveComponent, createVNode, createBlock, openBlock } = Vue return function render() { const _ctx = this @@ -30,7 +30,7 @@ return function render() { `; exports[`compiler: transform component slots implicit default slot 1`] = ` -"const { createVNode, resolveComponent, openBlock, createBlock } = Vue +"const { createVNode, resolveComponent, createBlock, openBlock } = Vue return function render() { const _ctx = this @@ -46,7 +46,7 @@ return function render() { `; exports[`compiler: transform component slots named slot with v-for w/ prefixIdentifiers: true 1`] = ` -"const { toString, resolveComponent, renderList, createSlots, createVNode, openBlock, createBlock } = Vue +"const { toString, resolveComponent, renderList, createSlots, createVNode, createBlock, openBlock } = Vue return function render() { const _ctx = this @@ -64,7 +64,7 @@ return function render() { `; exports[`compiler: transform component slots named slot with v-if + prefixIdentifiers: true 1`] = ` -"const { toString, resolveComponent, createSlots, createVNode, openBlock, createBlock } = Vue +"const { toString, resolveComponent, createSlots, createVNode, createBlock, openBlock } = Vue return function render() { const _ctx = this @@ -86,7 +86,7 @@ exports[`compiler: transform component slots named slot with v-if + v-else-if + return function render() { with (this) { - const { resolveComponent: _resolveComponent, createSlots: _createSlots, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue + const { resolveComponent: _resolveComponent, createSlots: _createSlots, createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue const _component_Comp = _resolveComponent(\\"Comp\\") @@ -115,7 +115,7 @@ exports[`compiler: transform component slots named slot with v-if 1`] = ` return function render() { with (this) { - const { resolveComponent: _resolveComponent, createSlots: _createSlots, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue + const { resolveComponent: _resolveComponent, createSlots: _createSlots, createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue const _component_Comp = _resolveComponent(\\"Comp\\") @@ -132,7 +132,7 @@ return function render() { `; exports[`compiler: transform component slots named slots 1`] = ` -"const { toString, resolveComponent, createVNode, openBlock, createBlock } = Vue +"const { toString, resolveComponent, createVNode, createBlock, openBlock } = Vue return function render() { const _ctx = this @@ -147,7 +147,7 @@ return function render() { `; exports[`compiler: transform component slots nested slots scoping 1`] = ` -"const { toString, resolveComponent, createVNode, openBlock, createBlock } = Vue +"const { toString, resolveComponent, createVNode, createBlock, openBlock } = Vue return function render() { const _ctx = this diff --git a/packages/compiler-core/__tests__/transforms/transformElement.spec.ts b/packages/compiler-core/__tests__/transforms/transformElement.spec.ts index 2bd6e186c..fb6230aeb 100644 --- a/packages/compiler-core/__tests__/transforms/transformElement.spec.ts +++ b/packages/compiler-core/__tests__/transforms/transformElement.spec.ts @@ -1,10 +1,4 @@ -import { - ElementNode, - CompilerOptions, - parse, - transform, - ErrorCodes -} from '../../src' +import { CompilerOptions, parse, transform, ErrorCodes } from '../../src' import { RESOLVE_COMPONENT, CREATE_VNODE, @@ -35,12 +29,14 @@ function parseWithElementTransform( root: RootNode node: CallExpression } { - const ast = parse(template, options) + // wrap raw template in an extra div so that it doesn't get turned into a + // block as root node + const ast = parse(`
${template}
`, options) transform(ast, { nodeTransforms: [optimizeText, transformElement], ...options }) - const codegenNode = (ast.children[0] as ElementNode) + const codegenNode = (ast as any).children[0].children[0] .codegenNode as CallExpression expect(codegenNode.type).toBe(NodeTypes.JS_CALL_EXPRESSION) return { diff --git a/packages/compiler-core/__tests__/transforms/vFor.spec.ts b/packages/compiler-core/__tests__/transforms/vFor.spec.ts index ff6a4d458..8763d74e3 100644 --- a/packages/compiler-core/__tests__/transforms/vFor.spec.ts +++ b/packages/compiler-core/__tests__/transforms/vFor.spec.ts @@ -22,7 +22,8 @@ import { CREATE_BLOCK, FRAGMENT, RENDER_LIST, - RENDER_SLOT + RENDER_SLOT, + APPLY_DIRECTIVES } from '../../src/runtimeHelpers' import { PatchFlags } from '@vue/runtime-dom' import { createObjectMatcher, genFlagText } from '../testUtils' @@ -845,5 +846,28 @@ describe('compiler: v-for', () => { }) expect(generate(root).code).toMatchSnapshot() }) + + test('v-for on element with custom directive', () => { + const { + root, + node: { codegenNode } + } = parseWithForTransform('
') + const { returns } = assertSharedCodegen(codegenNode, false, true) + expect(returns).toMatchObject({ + type: NodeTypes.JS_SEQUENCE_EXPRESSION, + expressions: [ + { callee: OPEN_BLOCK }, + // should wrap applyDirectives() around createBlock() + { + callee: APPLY_DIRECTIVES, + arguments: [ + { callee: CREATE_BLOCK }, + { type: NodeTypes.JS_ARRAY_EXPRESSION } + ] + } + ] + }) + expect(generate(root).code).toMatchSnapshot() + }) }) }) diff --git a/packages/compiler-core/src/ast.ts b/packages/compiler-core/src/ast.ts index dcfc3732b..6a915d85c 100644 --- a/packages/compiler-core/src/ast.ts +++ b/packages/compiler-core/src/ast.ts @@ -114,19 +114,12 @@ export interface BaseElementNode extends Node { export interface PlainElementNode extends BaseElementNode { tagType: ElementTypes.ELEMENT - codegenNode: - | ElementCodegenNode - | CodegenNodeWithDirective - | undefined - // | SimpleExpressionNode (only when hoisted) + codegenNode: ElementCodegenNode | undefined | SimpleExpressionNode // only when hoisted } export interface ComponentNode extends BaseElementNode { tagType: ElementTypes.COMPONENT - codegenNode: - | ComponentCodegenNode - | CodegenNodeWithDirective - | undefined + codegenNode: ComponentCodegenNode | undefined } export interface SlotOutletNode extends BaseElementNode { @@ -280,8 +273,8 @@ export interface ConditionalExpression extends Node { // Codegen Node Types ---------------------------------------------------------- // createVNode(...) -export interface ElementCodegenNode extends CallExpression { - callee: typeof CREATE_VNODE +export interface PlainElementCodegenNode extends CallExpression { + callee: typeof CREATE_VNODE | typeof CREATE_BLOCK arguments: // tag, props, children, patchFlag, dynamicProps | [string | RuntimeHelper] | [string | RuntimeHelper, PropsExpression] @@ -301,13 +294,13 @@ export interface ElementCodegenNode extends CallExpression { ] } -export type ElementCodegenNodeWithDirective = CodegenNodeWithDirective< - ElementCodegenNode -> +export type ElementCodegenNode = + | PlainElementCodegenNode + | CodegenNodeWithDirective // createVNode(...) -export interface ComponentCodegenNode extends CallExpression { - callee: typeof CREATE_VNODE +export interface PlainComponentCodegenNode extends CallExpression { + callee: typeof CREATE_VNODE | typeof CREATE_BLOCK arguments: // Comp, props, slots, patchFlag, dynamicProps | [string | RuntimeHelper] | [string | RuntimeHelper, PropsExpression] @@ -327,9 +320,9 @@ export interface ComponentCodegenNode extends CallExpression { ] } -export type CompoenntCodegenNodeWithDirective = CodegenNodeWithDirective< - ComponentCodegenNode -> +export type ComponentCodegenNode = + | PlainComponentCodegenNode + | CodegenNodeWithDirective export type SlotsExpression = SlotsObjectExpression | DynamicSlotsExpression @@ -417,6 +410,11 @@ export interface SlotOutletCodegenNode extends CallExpression { ] } +export type BlockCodegenNode = + | ElementCodegenNode + | ComponentCodegenNode + | SlotOutletCodegenNode + export interface IfCodegenNode extends SequenceExpression { expressions: [OpenBlockExpression, IfConditionalExpression] } @@ -449,28 +447,6 @@ export interface OpenBlockExpression extends CallExpression { arguments: [] } -export type BlockCodegenNode = - | BlockElementCodegenNode - | BlockComponentCodegenNode - | BlockElementCodegenNodeWithDirective - | BlockComponentCodegenNodeWithDirective - -export type BlockElementCodegenNode = ElementCodegenNode & { - callee: typeof CREATE_BLOCK -} - -export type BlockComponentCodegenNode = ComponentCodegenNode & { - callee: typeof CREATE_BLOCK -} - -export type BlockElementCodegenNodeWithDirective = CodegenNodeWithDirective< - BlockElementCodegenNode -> - -export type BlockComponentCodegenNodeWithDirective = CodegenNodeWithDirective< - BlockComponentCodegenNode -> - // AST Utilities --------------------------------------------------------------- // Some expressions, e.g. sequence and conditional expressions, are never @@ -552,13 +528,15 @@ export function createCompoundExpression( } } -type InferCodegenNodeType = T extends typeof CREATE_VNODE - ? ElementCodegenNode | ComponentCodegenNode - : T extends typeof CREATE_BLOCK - ? BlockElementCodegenNode | BlockComponentCodegenNode - : T extends typeof APPLY_DIRECTIVES - ? ElementCodegenNodeWithDirective | CompoenntCodegenNodeWithDirective - : T extends typeof RENDER_SLOT ? SlotOutletCodegenNode : CallExpression +type InferCodegenNodeType = T extends + | typeof CREATE_VNODE + | typeof CREATE_BLOCK + ? PlainElementCodegenNode | PlainComponentCodegenNode + : T extends typeof APPLY_DIRECTIVES + ? + | CodegenNodeWithDirective + | CodegenNodeWithDirective + : T extends typeof RENDER_SLOT ? SlotOutletCodegenNode : CallExpression export function createCallExpression( callee: T, diff --git a/packages/compiler-core/src/transform.ts b/packages/compiler-core/src/transform.ts index 54977c35c..4e8877f30 100644 --- a/packages/compiler-core/src/transform.ts +++ b/packages/compiler-core/src/transform.ts @@ -10,7 +10,10 @@ import { createSimpleExpression, JSChildNode, SimpleExpressionNode, - ElementTypes + ElementTypes, + ElementCodegenNode, + ComponentCodegenNode, + createCallExpression } from './ast' import { isString, isArray } from '@vue/shared' import { CompilerError, defaultOnError } from './errors' @@ -20,7 +23,9 @@ import { CREATE_VNODE, FRAGMENT, RuntimeHelper, - helperNameMap + helperNameMap, + APPLY_DIRECTIVES, + CREATE_BLOCK } from './runtimeHelpers' import { isVSlot, createBlockExpression } from './utils' import { hoistStatic, isSingleElementRoot } from './transforms/hoistStatic' @@ -147,7 +152,7 @@ function createTransformContext( } const list = context.parent!.children const removalIndex = node - ? list.indexOf(node as any) + ? list.indexOf(node) : context.currentNode ? context.childIndex : -1 @@ -230,24 +235,38 @@ function finalizeRoot(root: RootNode, context: TransformContext) { const { helper } = context const { children } = root const child = children[0] - if (isSingleElementRoot(root, child) && child.codegenNode) { - // turn root element into a block - root.codegenNode = createBlockExpression( - child.codegenNode.arguments, - context - ) - } else if (children.length === 1) { - // - single , IfNode, ForNode: already blocks. - // - single text node: always patched. - // - transform calls without transformElement (only during tests) - // Just generate the node as-is - root.codegenNode = child + if (children.length === 1) { + // if the single child is an element, turn it into a block. + if (isSingleElementRoot(root, child) && child.codegenNode) { + // single element root is never hoisted so codegenNode will never be + // SimpleExpressionNode + const codegenNode = child.codegenNode as + | ElementCodegenNode + | ComponentCodegenNode + if (codegenNode.callee === APPLY_DIRECTIVES) { + codegenNode.arguments[0].callee = helper(CREATE_BLOCK) + } else { + codegenNode.callee = helper(CREATE_BLOCK) + } + root.codegenNode = createBlockExpression(codegenNode, context) + } else { + // - single , IfNode, ForNode: already blocks. + // - single text node: always patched. + // root codegen falls through via genNode() + root.codegenNode = child + } } else if (children.length > 1) { // root has multiple nodes - return a fragment block. root.codegenNode = createBlockExpression( - [helper(FRAGMENT), `null`, root.children], + createCallExpression(helper(CREATE_BLOCK), [ + helper(FRAGMENT), + `null`, + root.children + ]), context ) + } else { + // no children = noop. codegen will return null. } // finalize meta information root.helpers = [...context.helpers] diff --git a/packages/compiler-core/src/transforms/hoistStatic.ts b/packages/compiler-core/src/transforms/hoistStatic.ts index b949db22a..6760a4397 100644 --- a/packages/compiler-core/src/transforms/hoistStatic.ts +++ b/packages/compiler-core/src/transforms/hoistStatic.ts @@ -2,10 +2,8 @@ import { RootNode, NodeTypes, TemplateChildNode, - ElementNode, ElementTypes, ElementCodegenNode, - ElementCodegenNodeWithDirective, PlainElementNode, ComponentNode, TemplateNode @@ -51,7 +49,7 @@ function walk( ) { if (!doNotHoistNode && isStaticNode(child, resultCache)) { // whole tree is static - ;(child as any).codegenNode = context.hoist(child.codegenNode!) + child.codegenNode = context.hoist(child.codegenNode!) continue } else { // node may contain dynamic children, but its props may be eligible for @@ -62,7 +60,7 @@ function walk( flag === PatchFlags.NEED_PATCH || flag === PatchFlags.TEXT ) { - let codegenNode = child.codegenNode! + let codegenNode = child.codegenNode as ElementCodegenNode if (codegenNode.callee === APPLY_DIRECTIVES) { codegenNode = codegenNode.arguments[0] } @@ -88,10 +86,8 @@ function walk( } } -function getPatchFlag(node: ElementNode): number | undefined { - let codegenNode = node.codegenNode as - | ElementCodegenNode - | ElementCodegenNodeWithDirective +function getPatchFlag(node: PlainElementNode): number | undefined { + let codegenNode = node.codegenNode as ElementCodegenNode if (codegenNode.callee === APPLY_DIRECTIVES) { codegenNode = codegenNode.arguments[0] } diff --git a/packages/compiler-core/src/transforms/vFor.ts b/packages/compiler-core/src/transforms/vFor.ts index 4e92e0fb8..674b43b5b 100644 --- a/packages/compiler-core/src/transforms/vFor.ts +++ b/packages/compiler-core/src/transforms/vFor.ts @@ -15,7 +15,7 @@ import { createObjectExpression, createObjectProperty, ForCodegenNode, - PlainElementNode + ElementCodegenNode } from '../ast' import { createCompilerError, ErrorCodes } from '../errors' import { @@ -30,11 +30,11 @@ import { RENDER_LIST, OPEN_BLOCK, CREATE_BLOCK, - FRAGMENT + FRAGMENT, + APPLY_DIRECTIVES } from '../runtimeHelpers' import { processExpression } from './transformExpression' import { PatchFlags, PatchFlagNames } from '@vue/shared' -import { PropsExpression } from './transformElement' export const transformFor = createStructuralDirectiveTransform( 'for', @@ -124,34 +124,29 @@ export const transformFor = createStructuralDirectiveTransform( // // we need to inject the key to the renderSlot() call. // the props for renderSlot is passed as the 3rd argument. - const existingProps = childBlock.arguments[2] as - | PropsExpression - | undefined - | 'null' - childBlock.arguments[2] = injectProp( - existingProps, - keyProperty, - context - ) + injectProp(childBlock, keyProperty, context) } } else if (isTemplate) { //