diff --git a/packages/compiler-core/__tests__/__snapshots__/codegen.spec.ts.snap b/packages/compiler-core/__tests__/__snapshots__/codegen.spec.ts.snap
index 2bdb4afa4..a9591f922 100644
--- a/packages/compiler-core/__tests__/__snapshots__/codegen.spec.ts.snap
+++ b/packages/compiler-core/__tests__/__snapshots__/codegen.spec.ts.snap
@@ -54,7 +54,7 @@ return function render(_ctx, _cache) {
[foo + bar]: bar
}, [
_createElementVNode("p", { "some-key": "foo" })
- ], 16)
+ ], 16 /* FULL_PROPS */)
}
}"
`;
@@ -98,7 +98,7 @@ exports[`compiler: codegen > forNode 1`] = `
"
return function render(_ctx, _cache) {
with (_ctx) {
- return (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(), 1))
+ return (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(), 1 /* TEXT */))
}
}"
`;
diff --git a/packages/compiler-core/__tests__/codegen.spec.ts b/packages/compiler-core/__tests__/codegen.spec.ts
index 9c9230756..4a5ba7d5c 100644
--- a/packages/compiler-core/__tests__/codegen.spec.ts
+++ b/packages/compiler-core/__tests__/codegen.spec.ts
@@ -267,7 +267,7 @@ describe('compiler: codegen', () => {
disableTracking: true,
props: undefined,
children: createCallExpression(RENDER_LIST),
- patchFlag: '1',
+ patchFlag: PatchFlags.TEXT,
dynamicProps: undefined,
directives: undefined,
loc: locStub,
@@ -303,7 +303,7 @@ describe('compiler: codegen', () => {
disableTracking: false,
props: undefined,
children: createCallExpression(RENDER_LIST),
- patchFlag: genFlagText(PatchFlags.STABLE_FRAGMENT),
+ patchFlag: PatchFlags.STABLE_FRAGMENT,
dynamicProps: undefined,
directives: undefined,
loc: locStub,
@@ -364,7 +364,7 @@ describe('compiler: codegen', () => {
),
],
// flag
- PatchFlags.FULL_PROPS + '',
+ PatchFlags.FULL_PROPS,
),
}),
)
@@ -375,7 +375,7 @@ describe('compiler: codegen', () => {
[foo + bar]: bar
}, [
_${helperNameMap[CREATE_ELEMENT_VNODE]}("p", { "some-key": "foo" })
- ], ${PatchFlags.FULL_PROPS})`)
+ ], ${genFlagText(PatchFlags.FULL_PROPS)})`)
expect(code).toMatchSnapshot()
})
@@ -666,11 +666,14 @@ describe('compiler: codegen', () => {
})
test('with patchFlag and no children/props', () => {
- expect(genCode(createVNodeCall(null, `"div"`, undefined, undefined, '1')))
- .toMatchInlineSnapshot(`
- "return _createElementVNode("div", null, null, 1)
- "
- `)
+ expect(
+ genCode(
+ createVNodeCall(null, `"div"`, undefined, undefined, PatchFlags.TEXT),
+ ),
+ ).toMatchInlineSnapshot(`
+ "return _createElementVNode("div", null, null, 1 /* TEXT */)
+ "
+ `)
})
test('as block', () => {
diff --git a/packages/compiler-core/__tests__/transform.spec.ts b/packages/compiler-core/__tests__/transform.spec.ts
index a56be51bc..0946d3648 100644
--- a/packages/compiler-core/__tests__/transform.spec.ts
+++ b/packages/compiler-core/__tests__/transform.spec.ts
@@ -19,7 +19,6 @@ import { transformFor } from '../src/transforms/vFor'
import { transformElement } from '../src/transforms/transformElement'
import { transformSlotOutlet } from '../src/transforms/transformSlotOutlet'
import { transformText } from '../src/transforms/transformText'
-import { genFlagText } from './testUtils'
import { PatchFlags } from '@vue/shared'
describe('compiler: transform', () => {
@@ -358,7 +357,7 @@ describe('compiler: transform', () => {
{ type: NodeTypes.ELEMENT, tag: `div` },
{ type: NodeTypes.ELEMENT, tag: `div` },
] as any,
- genFlagText(PatchFlags.STABLE_FRAGMENT),
+ PatchFlags.STABLE_FRAGMENT,
),
)
})
@@ -374,10 +373,7 @@ describe('compiler: transform', () => {
{ type: NodeTypes.ELEMENT, tag: `div` },
{ type: NodeTypes.COMMENT },
] as any,
- genFlagText([
- PatchFlags.STABLE_FRAGMENT,
- PatchFlags.DEV_ROOT_FRAGMENT,
- ]),
+ PatchFlags.STABLE_FRAGMENT | PatchFlags.DEV_ROOT_FRAGMENT,
),
)
})
diff --git a/packages/compiler-core/__tests__/transforms/hoistStatic.spec.ts b/packages/compiler-core/__tests__/transforms/hoistStatic.spec.ts
index d6c46b52e..d5a34243b 100644
--- a/packages/compiler-core/__tests__/transforms/hoistStatic.spec.ts
+++ b/packages/compiler-core/__tests__/transforms/hoistStatic.spec.ts
@@ -21,7 +21,7 @@ import { transformIf } from '../../src/transforms/vIf'
import { transformFor } from '../../src/transforms/vFor'
import { transformBind } from '../../src/transforms/vBind'
import { transformOn } from '../../src/transforms/vOn'
-import { createObjectMatcher, genFlagText } from '../testUtils'
+import { createObjectMatcher } from '../testUtils'
import { transformText } from '../../src/transforms/transformText'
import { PatchFlags } from '@vue/shared'
@@ -180,7 +180,7 @@ describe('compiler: hoistStatic transform', () => {
id: `[foo]`,
}),
children: undefined,
- patchFlag: genFlagText(PatchFlags.PROPS),
+ patchFlag: PatchFlags.PROPS,
dynamicProps: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: `_hoisted_1`,
@@ -242,7 +242,7 @@ describe('compiler: hoistStatic transform', () => {
ref: `[foo]`,
}),
children: undefined,
- patchFlag: genFlagText(PatchFlags.NEED_PATCH),
+ patchFlag: PatchFlags.NEED_PATCH,
},
},
])
@@ -263,7 +263,7 @@ describe('compiler: hoistStatic transform', () => {
content: `_hoisted_1`,
},
children: undefined,
- patchFlag: genFlagText(PatchFlags.NEED_PATCH),
+ patchFlag: PatchFlags.NEED_PATCH,
directives: {
type: NodeTypes.JS_ARRAY_EXPRESSION,
},
@@ -286,7 +286,7 @@ describe('compiler: hoistStatic transform', () => {
tag: `"div"`,
props: { content: `_hoisted_1` },
children: { type: NodeTypes.INTERPOLATION },
- patchFlag: genFlagText(PatchFlags.TEXT),
+ patchFlag: PatchFlags.TEXT,
},
},
])
@@ -365,7 +365,7 @@ describe('compiler: hoistStatic transform', () => {
type: NodeTypes.JS_CALL_EXPRESSION,
callee: RENDER_LIST,
},
- patchFlag: genFlagText(PatchFlags.UNKEYED_FRAGMENT),
+ patchFlag: PatchFlags.UNKEYED_FRAGMENT,
})
const innerBlockCodegen = forBlockCodegen!.children.arguments[1]
expect(innerBlockCodegen.returns).toMatchObject({
@@ -496,7 +496,7 @@ describe('compiler: hoistStatic transform', () => {
constType: ConstantTypes.NOT_CONSTANT,
},
},
- patchFlag: `1 /* TEXT */`,
+ patchFlag: PatchFlags.TEXT,
},
},
],
diff --git a/packages/compiler-core/__tests__/transforms/transformElement.spec.ts b/packages/compiler-core/__tests__/transforms/transformElement.spec.ts
index 10b9747d1..bf3510a05 100644
--- a/packages/compiler-core/__tests__/transforms/transformElement.spec.ts
+++ b/packages/compiler-core/__tests__/transforms/transformElement.spec.ts
@@ -37,7 +37,7 @@ import { transformStyle } from '../../../compiler-dom/src/transforms/transformSt
import { transformOn } from '../../src/transforms/vOn'
import { transformBind } from '../../src/transforms/vBind'
import { PatchFlags } from '@vue/shared'
-import { createObjectMatcher, genFlagText } from '../testUtils'
+import { createObjectMatcher } from '../testUtils'
import { transformText } from '../../src/transforms/transformText'
import { parseWithForTransform } from './vFor.spec'
@@ -521,7 +521,7 @@ describe('compiler: element transform', () => {
// keep-alive should not compile content to slots
children: [{ type: NodeTypes.ELEMENT, tag: 'span' }],
// should get a dynamic slots flag to force updates
- patchFlag: genFlagText(PatchFlags.DYNAMIC_SLOTS),
+ patchFlag: PatchFlags.DYNAMIC_SLOTS,
})
}
@@ -588,7 +588,7 @@ describe('compiler: element transform', () => {
})
// should factor in props returned by custom directive transforms
// in patchFlag analysis
- expect(node.patchFlag).toMatch(PatchFlags.PROPS + '')
+ expect(node.patchFlag).toBe(PatchFlags.PROPS)
expect(node.dynamicProps).toMatch(`"bar"`)
})
@@ -612,7 +612,7 @@ describe('compiler: element transform', () => {
tag: `"div"`,
props: undefined,
children: undefined,
- patchFlag: genFlagText(PatchFlags.NEED_PATCH), // should generate appropriate flag
+ patchFlag: PatchFlags.NEED_PATCH, // should generate appropriate flag
directives: {
type: NodeTypes.JS_ARRAY_EXPRESSION,
elements: [
@@ -945,26 +945,26 @@ describe('compiler: element transform', () => {
expect(node.patchFlag).toBeUndefined()
const { node: node2 } = parseWithBind(`
{{ foo }}
`)
- expect(node2.patchFlag).toBe(genFlagText(PatchFlags.TEXT))
+ expect(node2.patchFlag).toBe(PatchFlags.TEXT)
// multiple nodes, merged with optimize text
const { node: node3 } = parseWithBind(`foo {{ bar }} baz
`)
- expect(node3.patchFlag).toBe(genFlagText(PatchFlags.TEXT))
+ expect(node3.patchFlag).toBe(PatchFlags.TEXT)
})
test('CLASS', () => {
const { node } = parseWithBind(``)
- expect(node.patchFlag).toBe(genFlagText(PatchFlags.CLASS))
+ expect(node.patchFlag).toBe(PatchFlags.CLASS)
})
test('STYLE', () => {
const { node } = parseWithBind(``)
- expect(node.patchFlag).toBe(genFlagText(PatchFlags.STYLE))
+ expect(node.patchFlag).toBe(PatchFlags.STYLE)
})
test('PROPS', () => {
const { node } = parseWithBind(``)
- expect(node.patchFlag).toBe(genFlagText(PatchFlags.PROPS))
+ expect(node.patchFlag).toBe(PatchFlags.PROPS)
expect(node.dynamicProps).toBe(`["foo", "baz"]`)
})
@@ -973,7 +973,7 @@ describe('compiler: element transform', () => {
``,
)
expect(node.patchFlag).toBe(
- genFlagText([PatchFlags.CLASS, PatchFlags.STYLE, PatchFlags.PROPS]),
+ PatchFlags.CLASS | PatchFlags.STYLE | PatchFlags.PROPS,
)
expect(node.dynamicProps).toBe(`["foo", "baz"]`)
})
@@ -983,40 +983,40 @@ describe('compiler: element transform', () => {
const { node } = parseWithBind(
``,
)
- expect(node.patchFlag).toBe(genFlagText(PatchFlags.PROPS))
+ expect(node.patchFlag).toBe(PatchFlags.PROPS)
expect(node.dynamicProps).toBe(`["id", "class", "style"]`)
})
test('FULL_PROPS (v-bind)', () => {
const { node } = parseWithBind(``)
- expect(node.patchFlag).toBe(genFlagText(PatchFlags.FULL_PROPS))
+ expect(node.patchFlag).toBe(PatchFlags.FULL_PROPS)
})
test('FULL_PROPS (dynamic key)', () => {
const { node } = parseWithBind(``)
- expect(node.patchFlag).toBe(genFlagText(PatchFlags.FULL_PROPS))
+ expect(node.patchFlag).toBe(PatchFlags.FULL_PROPS)
})
test('FULL_PROPS (w/ others)', () => {
const { node } = parseWithBind(
``,
)
- expect(node.patchFlag).toBe(genFlagText(PatchFlags.FULL_PROPS))
+ expect(node.patchFlag).toBe(PatchFlags.FULL_PROPS)
})
test('NEED_PATCH (static ref)', () => {
const { node } = parseWithBind(``)
- expect(node.patchFlag).toBe(genFlagText(PatchFlags.NEED_PATCH))
+ expect(node.patchFlag).toBe(PatchFlags.NEED_PATCH)
})
test('NEED_PATCH (dynamic ref)', () => {
const { node } = parseWithBind(``)
- expect(node.patchFlag).toBe(genFlagText(PatchFlags.NEED_PATCH))
+ expect(node.patchFlag).toBe(PatchFlags.NEED_PATCH)
})
test('NEED_PATCH (custom directives)', () => {
const { node } = parseWithBind(``)
- expect(node.patchFlag).toBe(genFlagText(PatchFlags.NEED_PATCH))
+ expect(node.patchFlag).toBe(PatchFlags.NEED_PATCH)
})
test('NEED_PATCH (vnode hooks)', () => {
@@ -1025,7 +1025,7 @@ describe('compiler: element transform', () => {
cacheHandlers: true,
}).ast
const node = (root as any).children[0].codegenNode
- expect(node.patchFlag).toBe(genFlagText(PatchFlags.NEED_PATCH))
+ expect(node.patchFlag).toBe(PatchFlags.NEED_PATCH)
})
test('script setup inline mode template ref (binding exists)', () => {
@@ -1120,7 +1120,7 @@ describe('compiler: element transform', () => {
},
})
// should only have props flag
- expect(node.patchFlag).toBe(genFlagText(PatchFlags.PROPS))
+ expect(node.patchFlag).toBe(PatchFlags.PROPS)
const { node: node2 } = parseWithElementTransform(
``,
@@ -1130,21 +1130,15 @@ describe('compiler: element transform', () => {
},
},
)
- expect(node2.patchFlag).toBe(
- genFlagText([PatchFlags.PROPS, PatchFlags.NEED_HYDRATION]),
- )
+ expect(node2.patchFlag).toBe(PatchFlags.PROPS | PatchFlags.NEED_HYDRATION)
})
test('NEED_HYDRATION for v-bind.prop', () => {
const { node } = parseWithBind(``)
- expect(node.patchFlag).toBe(
- genFlagText([PatchFlags.PROPS, PatchFlags.NEED_HYDRATION]),
- )
+ expect(node.patchFlag).toBe(PatchFlags.PROPS | PatchFlags.NEED_HYDRATION)
const { node: node2 } = parseWithBind(``)
- expect(node2.patchFlag).toBe(
- genFlagText([PatchFlags.PROPS, PatchFlags.NEED_HYDRATION]),
- )
+ expect(node2.patchFlag).toBe(PatchFlags.PROPS | PatchFlags.NEED_HYDRATION)
})
// #5870
@@ -1157,9 +1151,7 @@ describe('compiler: element transform', () => {
},
},
)
- expect(node.patchFlag).toBe(
- genFlagText([PatchFlags.PROPS, PatchFlags.NEED_HYDRATION]),
- )
+ expect(node.patchFlag).toBe(PatchFlags.PROPS | PatchFlags.NEED_HYDRATION)
})
test('should not have PROPS patchflag for constant v-on handlers', () => {
@@ -1173,7 +1165,7 @@ describe('compiler: element transform', () => {
},
})
// should only have hydration flag
- expect(node.patchFlag).toBe(genFlagText(PatchFlags.NEED_HYDRATION))
+ expect(node.patchFlag).toBe(PatchFlags.NEED_HYDRATION)
})
})
diff --git a/packages/compiler-core/__tests__/transforms/vFor.spec.ts b/packages/compiler-core/__tests__/transforms/vFor.spec.ts
index 94f75f2a6..d0e95fcbc 100644
--- a/packages/compiler-core/__tests__/transforms/vFor.spec.ts
+++ b/packages/compiler-core/__tests__/transforms/vFor.spec.ts
@@ -18,8 +18,8 @@ import {
import { ErrorCodes } from '../../src/errors'
import { type CompilerOptions, generate } from '../../src'
import { FRAGMENT, RENDER_LIST, RENDER_SLOT } from '../../src/runtimeHelpers'
-import { PatchFlagNames, PatchFlags } from '@vue/shared'
-import { createObjectMatcher, genFlagText } from '../testUtils'
+import { PatchFlags } from '@vue/shared'
+import { createObjectMatcher } from '../testUtils'
export function parseWithForTransform(
template: string,
@@ -696,10 +696,10 @@ describe('compiler: v-for', () => {
tag: FRAGMENT,
disableTracking,
patchFlag: !disableTracking
- ? genFlagText(PatchFlags.STABLE_FRAGMENT)
+ ? PatchFlags.STABLE_FRAGMENT
: keyed
- ? genFlagText(PatchFlags.KEYED_FRAGMENT)
- : genFlagText(PatchFlags.UNKEYED_FRAGMENT),
+ ? PatchFlags.KEYED_FRAGMENT
+ : PatchFlags.UNKEYED_FRAGMENT,
children: {
type: NodeTypes.JS_CALL_EXPRESSION,
callee: RENDER_LIST,
@@ -822,7 +822,7 @@ describe('compiler: v-for', () => {
constType: ConstantTypes.NOT_CONSTANT,
},
},
- patchFlag: genFlagText(PatchFlags.TEXT),
+ patchFlag: PatchFlags.TEXT,
},
})
expect(generate(root).code).toMatchSnapshot()
@@ -846,7 +846,7 @@ describe('compiler: v-for', () => {
{ type: NodeTypes.TEXT, content: `hello` },
{ type: NodeTypes.ELEMENT, tag: `span` },
],
- patchFlag: genFlagText(PatchFlags.STABLE_FRAGMENT),
+ patchFlag: PatchFlags.STABLE_FRAGMENT,
},
})
expect(generate(root).code).toMatchSnapshot()
@@ -950,7 +950,7 @@ describe('compiler: v-for', () => {
{ type: NodeTypes.TEXT, content: `hello` },
{ type: NodeTypes.ELEMENT, tag: `span` },
],
- patchFlag: genFlagText(PatchFlags.STABLE_FRAGMENT),
+ patchFlag: PatchFlags.STABLE_FRAGMENT,
},
})
expect(generate(root).code).toMatchSnapshot()
@@ -971,7 +971,7 @@ describe('compiler: v-for', () => {
}),
isBlock: true,
disableTracking: true,
- patchFlag: genFlagText(PatchFlags.UNKEYED_FRAGMENT),
+ patchFlag: PatchFlags.UNKEYED_FRAGMENT,
children: {
type: NodeTypes.JS_CALL_EXPRESSION,
callee: RENDER_LIST,
@@ -1009,7 +1009,7 @@ describe('compiler: v-for', () => {
}),
isBlock: true,
disableTracking: true,
- patchFlag: genFlagText(PatchFlags.UNKEYED_FRAGMENT),
+ patchFlag: PatchFlags.UNKEYED_FRAGMENT,
children: {
type: NodeTypes.JS_CALL_EXPRESSION,
callee: RENDER_LIST,
@@ -1048,9 +1048,7 @@ describe('compiler: v-for', () => {
const {
node: { codegenNode },
} = parseWithForTransform('test
')
- expect(codegenNode.patchFlag).toBe(
- `${PatchFlags.KEYED_FRAGMENT} /* ${PatchFlagNames[PatchFlags.KEYED_FRAGMENT]} */`,
- )
+ expect(codegenNode.patchFlag).toBe(PatchFlags.KEYED_FRAGMENT)
})
test('template v-for key w/ :key shorthand on template injected to the child', () => {
diff --git a/packages/compiler-core/__tests__/transforms/vSlot.spec.ts b/packages/compiler-core/__tests__/transforms/vSlot.spec.ts
index 3afcf0fc0..4766c2ca9 100644
--- a/packages/compiler-core/__tests__/transforms/vSlot.spec.ts
+++ b/packages/compiler-core/__tests__/transforms/vSlot.spec.ts
@@ -24,7 +24,7 @@ import {
trackVForSlotScopes,
} from '../../src/transforms/vSlot'
import { CREATE_SLOTS, RENDER_LIST } from '../../src/runtimeHelpers'
-import { createObjectMatcher, genFlagText } from '../testUtils'
+import { createObjectMatcher } from '../testUtils'
import { PatchFlags } from '@vue/shared'
import { transformFor } from '../../src/transforms/vFor'
import { transformIf } from '../../src/transforms/vIf'
@@ -432,7 +432,7 @@ describe('compiler: transform component slots', () => {
),
// nested slot should be forced dynamic, since scope variables
// are not tracked as dependencies of the slot.
- patchFlag: genFlagText(PatchFlags.DYNAMIC_SLOTS),
+ patchFlag: PatchFlags.DYNAMIC_SLOTS,
},
},
// test scope
@@ -474,9 +474,7 @@ describe('compiler: transform component slots', () => {
const div = ((root.children[0] as ForNode).children[0] as ElementNode)
.codegenNode as any
const comp = div.children[0]
- expect(comp.codegenNode.patchFlag).toBe(
- genFlagText(PatchFlags.DYNAMIC_SLOTS),
- )
+ expect(comp.codegenNode.patchFlag).toBe(PatchFlags.DYNAMIC_SLOTS)
})
test('should only force dynamic slots when actually using scope vars w/ prefixIdentifiers: true', () => {
@@ -494,7 +492,7 @@ describe('compiler: transform component slots', () => {
flag = (innerComp.codegenNode as VNodeCall).patchFlag
}
if (shouldForce) {
- expect(flag).toBe(genFlagText(PatchFlags.DYNAMIC_SLOTS))
+ expect(flag).toBe(PatchFlags.DYNAMIC_SLOTS)
} else {
expect(flag).toBeUndefined()
}
@@ -581,8 +579,8 @@ describe('compiler: transform component slots', () => {
},
],
})
- expect((root as any).children[0].codegenNode.patchFlag).toMatch(
- PatchFlags.DYNAMIC_SLOTS + '',
+ expect((root as any).children[0].codegenNode.patchFlag).toBe(
+ PatchFlags.DYNAMIC_SLOTS,
)
expect(generate(root).code).toMatchSnapshot()
})
@@ -630,8 +628,8 @@ describe('compiler: transform component slots', () => {
},
],
})
- expect((root as any).children[0].codegenNode.patchFlag).toMatch(
- PatchFlags.DYNAMIC_SLOTS + '',
+ expect((root as any).children[0].codegenNode.patchFlag).toBe(
+ PatchFlags.DYNAMIC_SLOTS,
)
expect(generate(root, { prefixIdentifiers: true }).code).toMatchSnapshot()
})
@@ -693,8 +691,8 @@ describe('compiler: transform component slots', () => {
},
],
})
- expect((root as any).children[0].codegenNode.patchFlag).toMatch(
- PatchFlags.DYNAMIC_SLOTS + '',
+ expect((root as any).children[0].codegenNode.patchFlag).toBe(
+ PatchFlags.DYNAMIC_SLOTS,
)
expect((root as any).children[0].children.length).toBe(3)
expect(generate(root).code).toMatchSnapshot()
@@ -744,8 +742,8 @@ describe('compiler: transform component slots', () => {
},
],
})
- expect((root as any).children[0].codegenNode.patchFlag).toMatch(
- PatchFlags.DYNAMIC_SLOTS + '',
+ expect((root as any).children[0].codegenNode.patchFlag).toBe(
+ PatchFlags.DYNAMIC_SLOTS,
)
expect(generate(root, { prefixIdentifiers: true }).code).toMatchSnapshot()
})
diff --git a/packages/compiler-core/src/ast.ts b/packages/compiler-core/src/ast.ts
index 91354b1b4..562e24e72 100644
--- a/packages/compiler-core/src/ast.ts
+++ b/packages/compiler-core/src/ast.ts
@@ -1,4 +1,4 @@
-import { isString } from '@vue/shared'
+import { type PatchFlags, isString } from '@vue/shared'
import {
CREATE_BLOCK,
CREATE_ELEMENT_BLOCK,
@@ -331,7 +331,7 @@ export interface VNodeCall extends Node {
| ForRenderListExpression // v-for fragment call
| SimpleExpressionNode // hoisted
| undefined
- patchFlag: string | undefined
+ patchFlag: PatchFlags | undefined
dynamicProps: string | SimpleExpressionNode | undefined
directives: DirectiveArguments | undefined
isBlock: boolean
@@ -561,7 +561,7 @@ export interface ForCodegenNode extends VNodeCall {
tag: typeof FRAGMENT
props: undefined
children: ForRenderListExpression
- patchFlag: string
+ patchFlag: PatchFlags
disableTracking: boolean
}
diff --git a/packages/compiler-core/src/codegen.ts b/packages/compiler-core/src/codegen.ts
index 39170bac5..4dd51133c 100644
--- a/packages/compiler-core/src/codegen.ts
+++ b/packages/compiler-core/src/codegen.ts
@@ -35,7 +35,13 @@ import {
isSimpleIdentifier,
toValidAssetId,
} from './utils'
-import { isArray, isString, isSymbol } from '@vue/shared'
+import {
+ PatchFlagNames,
+ type PatchFlags,
+ isArray,
+ isString,
+ isSymbol,
+} from '@vue/shared'
import {
CREATE_COMMENT,
CREATE_ELEMENT_VNODE,
@@ -843,6 +849,28 @@ function genVNodeCall(node: VNodeCall, context: CodegenContext) {
disableTracking,
isComponent,
} = node
+
+ // add dev annotations to patch flags
+ let patchFlagString
+ if (patchFlag) {
+ if (__DEV__) {
+ if (patchFlag < 0) {
+ // special flags (negative and mutually exclusive)
+ patchFlagString = patchFlag + ` /* ${PatchFlagNames[patchFlag]} */`
+ } else {
+ // bitwise flags
+ const flagNames = Object.keys(PatchFlagNames)
+ .map(Number)
+ .filter(n => n > 0 && patchFlag & n)
+ .map(n => PatchFlagNames[n as PatchFlags])
+ .join(`, `)
+ patchFlagString = patchFlag + ` /* ${flagNames} */`
+ }
+ } else {
+ patchFlagString = String(patchFlag)
+ }
+ }
+
if (directives) {
push(helper(WITH_DIRECTIVES) + `(`)
}
@@ -857,7 +885,7 @@ function genVNodeCall(node: VNodeCall, context: CodegenContext) {
: getVNodeHelper(context.inSSR, isComponent)
push(helper(callHelper) + `(`, NewlineType.None, node)
genNodeList(
- genNullableArgs([tag, props, children, patchFlag, dynamicProps]),
+ genNullableArgs([tag, props, children, patchFlagString, dynamicProps]),
context,
)
push(`)`)
diff --git a/packages/compiler-core/src/transform.ts b/packages/compiler-core/src/transform.ts
index 69821f7f8..83ed8a920 100644
--- a/packages/compiler-core/src/transform.ts
+++ b/packages/compiler-core/src/transform.ts
@@ -382,7 +382,7 @@ function createRootCodegen(root: RootNode, context: TransformContext) {
helper(FRAGMENT),
undefined,
root.children,
- patchFlag + (__DEV__ ? ` /* ${patchFlagText} */` : ``),
+ patchFlag,
undefined,
undefined,
true,
diff --git a/packages/compiler-core/src/transforms/hoistStatic.ts b/packages/compiler-core/src/transforms/hoistStatic.ts
index 67bdaa887..5942b7309 100644
--- a/packages/compiler-core/src/transforms/hoistStatic.ts
+++ b/packages/compiler-core/src/transforms/hoistStatic.ts
@@ -70,8 +70,7 @@ function walk(
: getConstantType(child, context)
if (constantType > ConstantTypes.NOT_CONSTANT) {
if (constantType >= ConstantTypes.CAN_HOIST) {
- ;(child.codegenNode as VNodeCall).patchFlag =
- PatchFlags.HOISTED + (__DEV__ ? ` /* HOISTED */` : ``)
+ ;(child.codegenNode as VNodeCall).patchFlag = PatchFlags.HOISTED
child.codegenNode = context.hoist(child.codegenNode!)
hoistedCount++
continue
@@ -81,9 +80,9 @@ function walk(
// hoisting.
const codegenNode = child.codegenNode!
if (codegenNode.type === NodeTypes.VNODE_CALL) {
- const flag = getPatchFlag(codegenNode)
+ const flag = codegenNode.patchFlag
if (
- (!flag ||
+ (flag === undefined ||
flag === PatchFlags.NEED_PATCH ||
flag === PatchFlags.TEXT) &&
getGeneratedPropsConstantType(child, context) >=
@@ -179,8 +178,7 @@ export function getConstantType(
) {
return ConstantTypes.NOT_CONSTANT
}
- const flag = getPatchFlag(codegenNode)
- if (!flag) {
+ if (codegenNode.patchFlag === undefined) {
let returnType = ConstantTypes.CAN_STRINGIFY
// Element itself has no patch flag. However we still need to check:
@@ -365,8 +363,3 @@ function getNodeProps(node: PlainElementNode) {
return codegenNode.props
}
}
-
-function getPatchFlag(node: VNodeCall): number | undefined {
- const flag = node.patchFlag
- return flag ? parseInt(flag, 10) : undefined
-}
diff --git a/packages/compiler-core/src/transforms/transformElement.ts b/packages/compiler-core/src/transforms/transformElement.ts
index b1be06db7..ebaf08375 100644
--- a/packages/compiler-core/src/transforms/transformElement.ts
+++ b/packages/compiler-core/src/transforms/transformElement.ts
@@ -23,7 +23,6 @@ import {
createVNodeCall,
} from '../ast'
import {
- PatchFlagNames,
PatchFlags,
camelize,
capitalize,
@@ -101,8 +100,7 @@ export const transformElement: NodeTransform = (node, context) => {
let vnodeProps: VNodeCall['props']
let vnodeChildren: VNodeCall['children']
- let vnodePatchFlag: VNodeCall['patchFlag']
- let patchFlag: number = 0
+ let patchFlag: VNodeCall['patchFlag'] | 0 = 0
let vnodeDynamicProps: VNodeCall['dynamicProps']
let dynamicPropNames: string[] | undefined
let vnodeDirectives: VNodeCall['directives']
@@ -206,27 +204,8 @@ export const transformElement: NodeTransform = (node, context) => {
}
// patchFlag & dynamicPropNames
- if (patchFlag !== 0) {
- if (__DEV__) {
- if (patchFlag < 0) {
- // special flags (negative and mutually exclusive)
- vnodePatchFlag =
- patchFlag + ` /* ${PatchFlagNames[patchFlag as PatchFlags]} */`
- } else {
- // bitwise flags
- const flagNames = Object.keys(PatchFlagNames)
- .map(Number)
- .filter(n => n > 0 && patchFlag & n)
- .map(n => PatchFlagNames[n as PatchFlags])
- .join(`, `)
- vnodePatchFlag = patchFlag + ` /* ${flagNames} */`
- }
- } else {
- vnodePatchFlag = String(patchFlag)
- }
- if (dynamicPropNames && dynamicPropNames.length) {
- vnodeDynamicProps = stringifyDynamicPropNames(dynamicPropNames)
- }
+ if (dynamicPropNames && dynamicPropNames.length) {
+ vnodeDynamicProps = stringifyDynamicPropNames(dynamicPropNames)
}
node.codegenNode = createVNodeCall(
@@ -234,7 +213,7 @@ export const transformElement: NodeTransform = (node, context) => {
vnodeTag,
vnodeProps,
vnodeChildren,
- vnodePatchFlag,
+ patchFlag === 0 ? undefined : patchFlag,
vnodeDynamicProps,
vnodeDirectives,
!!shouldUseBlock,
diff --git a/packages/compiler-core/src/transforms/vFor.ts b/packages/compiler-core/src/transforms/vFor.ts
index 16c48ede0..0db961528 100644
--- a/packages/compiler-core/src/transforms/vFor.ts
+++ b/packages/compiler-core/src/transforms/vFor.ts
@@ -46,7 +46,7 @@ import {
} from '../runtimeHelpers'
import { processExpression } from './transformExpression'
import { validateBrowserExpression } from '../validateExpression'
-import { PatchFlagNames, PatchFlags } from '@vue/shared'
+import { PatchFlags } from '@vue/shared'
import { transformBindShorthand } from './vBind'
export const transformFor = createStructuralDirectiveTransform(
@@ -109,8 +109,7 @@ export const transformFor = createStructuralDirectiveTransform(
helper(FRAGMENT),
undefined,
renderExp,
- fragmentFlag +
- (__DEV__ ? ` /* ${PatchFlagNames[fragmentFlag]} */` : ``),
+ fragmentFlag,
undefined,
undefined,
true /* isBlock */,
@@ -169,10 +168,7 @@ export const transformFor = createStructuralDirectiveTransform(
helper(FRAGMENT),
keyProperty ? createObjectExpression([keyProperty]) : undefined,
node.children,
- PatchFlags.STABLE_FRAGMENT +
- (__DEV__
- ? ` /* ${PatchFlagNames[PatchFlags.STABLE_FRAGMENT]} */`
- : ``),
+ PatchFlags.STABLE_FRAGMENT,
undefined,
undefined,
true,
diff --git a/packages/compiler-core/src/transforms/vIf.ts b/packages/compiler-core/src/transforms/vIf.ts
index a6437f89c..06255b25f 100644
--- a/packages/compiler-core/src/transforms/vIf.ts
+++ b/packages/compiler-core/src/transforms/vIf.ts
@@ -280,7 +280,7 @@ function createChildrenCodegenNode(
helper(FRAGMENT),
createObjectExpression([keyProperty]),
children,
- patchFlag + (__DEV__ ? ` /* ${patchFlagText} */` : ``),
+ patchFlag,
undefined,
undefined,
true,
diff --git a/packages/compiler-dom/__tests__/transforms/vHtml.spec.ts b/packages/compiler-dom/__tests__/transforms/vHtml.spec.ts
index a59a7a40a..bca2fdf95 100644
--- a/packages/compiler-dom/__tests__/transforms/vHtml.spec.ts
+++ b/packages/compiler-dom/__tests__/transforms/vHtml.spec.ts
@@ -6,10 +6,7 @@ import {
} from '@vue/compiler-core'
import { transformVHtml } from '../../src/transforms/vHtml'
import { transformElement } from '../../../compiler-core/src/transforms/transformElement'
-import {
- createObjectMatcher,
- genFlagText,
-} from '../../../compiler-core/__tests__/testUtils'
+import { createObjectMatcher } from '../../../compiler-core/__tests__/testUtils'
import { PatchFlags } from '@vue/shared'
import { DOMErrorCodes } from '../../src/errors'
@@ -34,7 +31,7 @@ describe('compiler: v-html transform', () => {
innerHTML: `[test]`,
}),
children: undefined,
- patchFlag: genFlagText(PatchFlags.PROPS),
+ patchFlag: PatchFlags.PROPS,
dynamicProps: `["innerHTML"]`,
})
})
@@ -53,7 +50,7 @@ describe('compiler: v-html transform', () => {
innerHTML: `[test]`,
}),
children: undefined, // <-- children should have been removed
- patchFlag: genFlagText(PatchFlags.PROPS),
+ patchFlag: PatchFlags.PROPS,
dynamicProps: `["innerHTML"]`,
})
})
diff --git a/packages/compiler-dom/__tests__/transforms/vOn.spec.ts b/packages/compiler-dom/__tests__/transforms/vOn.spec.ts
index 2e8072911..f53fbb69b 100644
--- a/packages/compiler-dom/__tests__/transforms/vOn.spec.ts
+++ b/packages/compiler-dom/__tests__/transforms/vOn.spec.ts
@@ -14,7 +14,6 @@ import { transformOn } from '../../src/transforms/vOn'
import { V_ON_WITH_KEYS, V_ON_WITH_MODIFIERS } from '../../src/runtimeHelpers'
import { transformElement } from '../../../compiler-core/src/transforms/transformElement'
import { transformExpression } from '../../../compiler-core/src/transforms/transformExpression'
-import { genFlagText } from '../../../compiler-core/__tests__/testUtils'
import { PatchFlags } from '@vue/shared'
function parseWithVOn(template: string, options: CompilerOptions = {}) {
@@ -272,7 +271,7 @@ describe('compiler-dom: transform v-on', () => {
// should not treat cached handler as dynamicProp, so it should have no
// dynamicProps flags and only the hydration flag
expect((root as any).children[0].codegenNode.patchFlag).toBe(
- genFlagText(PatchFlags.NEED_HYDRATION),
+ PatchFlags.NEED_HYDRATION,
)
expect(prop).toMatchObject({
key: {
@@ -300,6 +299,6 @@ describe('compiler-dom: transform v-on', () => {
},
})
// should only have hydration flag
- expect(node.patchFlag).toBe(genFlagText(PatchFlags.NEED_HYDRATION))
+ expect(node.patchFlag).toBe(PatchFlags.NEED_HYDRATION)
})
})
diff --git a/packages/compiler-dom/__tests__/transforms/vText.spec.ts b/packages/compiler-dom/__tests__/transforms/vText.spec.ts
index 1b717e833..e96ab2972 100644
--- a/packages/compiler-dom/__tests__/transforms/vText.spec.ts
+++ b/packages/compiler-dom/__tests__/transforms/vText.spec.ts
@@ -6,10 +6,7 @@ import {
} from '@vue/compiler-core'
import { transformVText } from '../../src/transforms/vText'
import { transformElement } from '../../../compiler-core/src/transforms/transformElement'
-import {
- createObjectMatcher,
- genFlagText,
-} from '../../../compiler-core/__tests__/testUtils'
+import { createObjectMatcher } from '../../../compiler-core/__tests__/testUtils'
import { PatchFlags } from '@vue/shared'
import { DOMErrorCodes } from '../../src/errors'
@@ -36,7 +33,7 @@ describe('compiler: v-text transform', () => {
},
}),
children: undefined,
- patchFlag: genFlagText(PatchFlags.PROPS),
+ patchFlag: PatchFlags.PROPS,
dynamicProps: `["textContent"]`,
})
})
@@ -57,7 +54,7 @@ describe('compiler: v-text transform', () => {
},
}),
children: undefined, // <-- children should have been removed
- patchFlag: genFlagText(PatchFlags.PROPS),
+ patchFlag: PatchFlags.PROPS,
dynamicProps: `["textContent"]`,
})
})
diff --git a/packages/runtime-core/__tests__/hydration.spec.ts b/packages/runtime-core/__tests__/hydration.spec.ts
index 53974bc93..60941d036 100644
--- a/packages/runtime-core/__tests__/hydration.spec.ts
+++ b/packages/runtime-core/__tests__/hydration.spec.ts
@@ -1317,76 +1317,83 @@ describe('SSR hydration', () => {
// #10607
test('update component stable slot (prod + optimized mode)', async () => {
__DEV__ = false
- const container = document.createElement('div')
- container.innerHTML = ``
- const Comp = {
- render(this: any) {
- return (
- openBlock(),
- createElementBlock('div', null, [renderSlot(this.$slots, 'default')])
- )
- },
- }
- const show = ref(false)
- const clicked = ref(false)
-
- const Wrapper = {
- setup() {
- const items = ref([])
- onMounted(() => {
- items.value = [1]
- })
- return () => {
+ try {
+ const container = document.createElement('div')
+ container.innerHTML = ``
+ const Comp = {
+ render(this: any) {
return (
openBlock(),
- createBlock(Comp, null, {
- default: withCtx(() => [
- createElementVNode('div', null, [
- createElementVNode('div', null, [
- clicked.value
- ? (openBlock(),
- createElementBlock('div', { key: 0 }, 'foo'))
- : createCommentVNode('v-if', true),
- ]),
- ]),
- createElementVNode(
- 'div',
- null,
- items.value.length,
- 1 /* TEXT */,
- ),
- ]),
- _: 1 /* STABLE */,
- })
+ createElementBlock('div', null, [
+ renderSlot(this.$slots, 'default'),
+ ])
)
- }
- },
- }
- createSSRApp({
- components: { Wrapper },
- data() {
- return { show }
- },
- template: ``,
- }).mount(container)
+ },
+ }
+ const show = ref(false)
+ const clicked = ref(false)
- await nextTick()
- expect(container.innerHTML).toBe(
- ``,
- )
+ const Wrapper = {
+ setup() {
+ const items = ref([])
+ onMounted(() => {
+ items.value = [1]
+ })
+ return () => {
+ return (
+ openBlock(),
+ createBlock(Comp, null, {
+ default: withCtx(() => [
+ createElementVNode('div', null, [
+ createElementVNode('div', null, [
+ clicked.value
+ ? (openBlock(),
+ createElementBlock('div', { key: 0 }, 'foo'))
+ : createCommentVNode('v-if', true),
+ ]),
+ ]),
+ createElementVNode(
+ 'div',
+ null,
+ items.value.length,
+ 1 /* TEXT */,
+ ),
+ ]),
+ _: 1 /* STABLE */,
+ })
+ )
+ }
+ },
+ }
+ createSSRApp({
+ components: { Wrapper },
+ data() {
+ return { show }
+ },
+ template: ``,
+ }).mount(container)
- show.value = true
- await nextTick()
- expect(async () => {
- clicked.value = true
await nextTick()
- }).not.toThrow("Cannot read properties of null (reading 'insertBefore')")
+ expect(container.innerHTML).toBe(
+ ``,
+ )
- await nextTick()
- expect(container.innerHTML).toBe(
- ``,
- )
- __DEV__ = true
+ show.value = true
+ await nextTick()
+ expect(async () => {
+ clicked.value = true
+ await nextTick()
+ }).not.toThrow("Cannot read properties of null (reading 'insertBefore')")
+
+ await nextTick()
+ expect(container.innerHTML).toBe(
+ ``,
+ )
+ } catch (e) {
+ throw e
+ } finally {
+ __DEV__ = true
+ }
})
describe('mismatch handling', () => {