diff --git a/packages/compiler-core/__tests__/__snapshots__/compile.spec.ts.snap b/packages/compiler-core/__tests__/__snapshots__/compile.spec.ts.snap index 1ac0c95bc..efbeb1be1 100644 --- a/packages/compiler-core/__tests__/__snapshots__/compile.spec.ts.snap +++ b/packages/compiler-core/__tests__/__snapshots__/compile.spec.ts.snap @@ -20,7 +20,7 @@ return function render() { _createVNode(\\"span\\", null, _toString(value + index)) ]) }))) - ], 2) + ], 2 /* CLASS */) } }" `; @@ -43,7 +43,7 @@ return function render() { createVNode(\\"span\\", null, toString(value + index)) ]) }))) - ], 2) + ], 2 /* CLASS */) }" `; @@ -65,6 +65,6 @@ export default function render() { createVNode(\\"span\\", null, _toString(value + index)) ]) }))) - ], 2) + ], 2 /* CLASS */) }" `; 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 1bc471f32..03ab9da4b 100644 --- a/packages/compiler-core/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap +++ b/packages/compiler-core/__tests__/transforms/__snapshots__/vSlot.spec.ts.snap @@ -16,7 +16,7 @@ return function render() { toString(_ctx.foo), toString(bar) ] - }, 256) + }, 256 /* DYNAMIC_SLOTS */) }" `; diff --git a/packages/compiler-core/__tests__/transforms/transformElement.spec.ts b/packages/compiler-core/__tests__/transforms/transformElement.spec.ts index 2ca90b952..7d2793c9b 100644 --- a/packages/compiler-core/__tests__/transforms/transformElement.spec.ts +++ b/packages/compiler-core/__tests__/transforms/transformElement.spec.ts @@ -319,7 +319,7 @@ describe('compiler: element transform', () => { ] }, `null`, - String(PatchFlags.NEED_PATCH) // should generate appropriate flag + `${PatchFlags.NEED_PATCH} /* NEED_PATCH */` // should generate appropriate flag ] }, { @@ -565,19 +565,19 @@ describe('compiler: element transform', () => { test('CLASS', () => { const { node } = parseWithBind(`
`) expect(node.arguments.length).toBe(4) - expect(node.arguments[3]).toBe(String(PatchFlags.CLASS)) + expect(node.arguments[3]).toBe(`${PatchFlags.CLASS} /* CLASS */`) }) test('STYLE', () => { const { node } = parseWithBind(`
`) expect(node.arguments.length).toBe(4) - expect(node.arguments[3]).toBe(String(PatchFlags.STYLE)) + expect(node.arguments[3]).toBe(`${PatchFlags.STYLE} /* STYLE */`) }) test('PROPS', () => { const { node } = parseWithBind(`
`) expect(node.arguments.length).toBe(5) - expect(node.arguments[3]).toBe(String(PatchFlags.PROPS)) + expect(node.arguments[3]).toBe(`${PatchFlags.PROPS} /* PROPS */`) expect(node.arguments[4]).toBe(`["foo", "baz"]`) }) @@ -587,7 +587,9 @@ describe('compiler: element transform', () => { ) expect(node.arguments.length).toBe(5) expect(node.arguments[3]).toBe( - String(PatchFlags.PROPS | PatchFlags.CLASS | PatchFlags.STYLE) + `${PatchFlags.PROPS | + PatchFlags.CLASS | + PatchFlags.STYLE} /* CLASS, STYLE, PROPS */` ) expect(node.arguments[4]).toBe(`["foo", "baz"]`) }) @@ -595,13 +597,17 @@ describe('compiler: element transform', () => { test('FULL_PROPS (v-bind)', () => { const { node } = parseWithBind(`
`) expect(node.arguments.length).toBe(4) - expect(node.arguments[3]).toBe(String(PatchFlags.FULL_PROPS)) + expect(node.arguments[3]).toBe( + `${PatchFlags.FULL_PROPS} /* FULL_PROPS */` + ) }) test('FULL_PROPS (dynamic key)', () => { const { node } = parseWithBind(`
`) expect(node.arguments.length).toBe(4) - expect(node.arguments[3]).toBe(String(PatchFlags.FULL_PROPS)) + expect(node.arguments[3]).toBe( + `${PatchFlags.FULL_PROPS} /* FULL_PROPS */` + ) }) test('FULL_PROPS (w/ others)', () => { @@ -609,26 +615,34 @@ describe('compiler: element transform', () => { `
` ) expect(node.arguments.length).toBe(4) - expect(node.arguments[3]).toBe(String(PatchFlags.FULL_PROPS)) + expect(node.arguments[3]).toBe( + `${PatchFlags.FULL_PROPS} /* FULL_PROPS */` + ) }) test('NEED_PATCH (static ref)', () => { const { node } = parseWithBind(`
`) expect(node.arguments.length).toBe(4) - expect(node.arguments[3]).toBe(String(PatchFlags.NEED_PATCH)) + expect(node.arguments[3]).toBe( + `${PatchFlags.NEED_PATCH} /* NEED_PATCH */` + ) }) test('NEED_PATCH (dynamic ref)', () => { const { node } = parseWithBind(`
`) expect(node.arguments.length).toBe(4) - expect(node.arguments[3]).toBe(String(PatchFlags.NEED_PATCH)) + expect(node.arguments[3]).toBe( + `${PatchFlags.NEED_PATCH} /* NEED_PATCH */` + ) }) test('NEED_PATCH (custom directives)', () => { const { node } = parseWithBind(`
`) const vnodeCall = node.arguments[0] as CallExpression expect(vnodeCall.arguments.length).toBe(4) - expect(vnodeCall.arguments[3]).toBe(String(PatchFlags.NEED_PATCH)) + expect(vnodeCall.arguments[3]).toBe( + `${PatchFlags.NEED_PATCH} /* NEED_PATCH */` + ) }) }) }) diff --git a/packages/compiler-core/src/transforms/transformElement.ts b/packages/compiler-core/src/transforms/transformElement.ts index a697cc9de..ae9155a24 100644 --- a/packages/compiler-core/src/transforms/transformElement.ts +++ b/packages/compiler-core/src/transforms/transformElement.ts @@ -16,7 +16,7 @@ import { Property, SourceLocation } from '../ast' -import { isArray, PatchFlags } from '@vue/shared' +import { isArray, PatchFlags, PatchFlagNames } from '@vue/shared' import { createCompilerError, ErrorCodes } from '../errors' import { CREATE_VNODE, @@ -99,7 +99,15 @@ export const transformElement: NodeTransform = (node, context) => { } args.push(`null`) } - args.push(String(patchFlag)) + if (__DEV__) { + const flagNames = Object.keys(PatchFlagNames) + .filter(n => patchFlag & Number(n)) + .map(n => PatchFlagNames[n as any]) + .join(`, `) + args.push(patchFlag + ` /* ${flagNames} */`) + } else { + args.push(patchFlag + '') + } if (dynamicPropNames && dynamicPropNames.length) { args.push( `[${dynamicPropNames.map(n => JSON.stringify(n)).join(`, `)}]` diff --git a/packages/runtime-core/__tests__/rendererFragment.spec.ts b/packages/runtime-core/__tests__/rendererFragment.spec.ts index a550de720..ec7c2444a 100644 --- a/packages/runtime-core/__tests__/rendererFragment.spec.ts +++ b/packages/runtime-core/__tests__/rendererFragment.spec.ts @@ -107,7 +107,12 @@ describe('renderer: fragment', () => { it('patch fragment children (compiler generated, unkeyed)', () => { const root = nodeOps.createElement('div') render( - createVNode(Fragment, null, [h('div', 'one'), 'two'], PatchFlags.UNKEYED), + createVNode( + Fragment, + null, + [h('div', 'one'), 'two'], + PatchFlags.UNKEYED_V_FOR + ), root ) expect(serializeInner(root)).toBe(`
one
two`) @@ -117,7 +122,7 @@ describe('renderer: fragment', () => { Fragment, null, [h('div', 'foo'), 'bar', 'baz'], - PatchFlags.UNKEYED + PatchFlags.UNKEYED_V_FOR ), root ) @@ -132,7 +137,7 @@ describe('renderer: fragment', () => { Fragment, null, [h('div', { key: 1 }, 'one'), h('div', { key: 2 }, 'two')], - PatchFlags.KEYED + PatchFlags.KEYED_V_FOR ), root ) @@ -146,7 +151,7 @@ describe('renderer: fragment', () => { Fragment, null, [h('div', { key: 2 }, 'two'), h('div', { key: 1 }, 'one')], - PatchFlags.KEYED + PatchFlags.KEYED_V_FOR ), root ) diff --git a/packages/runtime-core/src/createRenderer.ts b/packages/runtime-core/src/createRenderer.ts index a7dc9be6a..b2b6be6d7 100644 --- a/packages/runtime-core/src/createRenderer.ts +++ b/packages/runtime-core/src/createRenderer.ts @@ -1230,7 +1230,7 @@ export function createRenderer< // fast path const { patchFlag, shapeFlag } = n2 if (patchFlag) { - if (patchFlag & PatchFlags.KEYED) { + if (patchFlag & PatchFlags.KEYED_V_FOR) { // this could be either fully-keyed or mixed (some keyed some not) // presence of patchFlag means children are guaranteed to be arrays patchKeyedChildren( @@ -1244,7 +1244,7 @@ export function createRenderer< optimized ) return - } else if (patchFlag & PatchFlags.UNKEYED) { + } else if (patchFlag & PatchFlags.UNKEYED_V_FOR) { // unkeyed patchUnkeyedChildren( c1 as HostVNode[], diff --git a/packages/shared/src/patchFlags.ts b/packages/shared/src/patchFlags.ts index 13336c221..8c98cf2c9 100644 --- a/packages/shared/src/patchFlags.ts +++ b/packages/shared/src/patchFlags.ts @@ -47,12 +47,11 @@ export const enum PatchFlags { // value. NEED_PATCH = 1 << 5, - // Indicates a fragment or element with keyed or partially-keyed v-for - // children - KEYED = 1 << 6, + // Indicates a v-for fragment with keyed or partially keyed children + KEYED_V_FOR = 1 << 6, - // Indicates a fragment or element that contains unkeyed v-for children - UNKEYED = 1 << 7, + // Indicates a v-for fragment with unkeyed children. + UNKEYED_V_FOR = 1 << 7, // Indicates a component with dynamic slots (e.g. slot that references a v-for // iterated value, or dynamic slot names). @@ -68,6 +67,20 @@ export const PublicPatchFlags = { PROPS: PatchFlags.PROPS, NEED_PATCH: PatchFlags.NEED_PATCH, FULL_PROPS: PatchFlags.FULL_PROPS, - KEYED: PatchFlags.KEYED, - UNKEYED: PatchFlags.UNKEYED + KEYED_V_FOR: PatchFlags.KEYED_V_FOR, + UNKEYED_V_FOR: PatchFlags.UNKEYED_V_FOR, + DYNAMIC_SLOTS: PatchFlags.DYNAMIC_SLOTS +} + +// dev only flag -> name mapping +export const PatchFlagNames = { + [PatchFlags.TEXT]: `TEXT`, + [PatchFlags.CLASS]: `CLASS`, + [PatchFlags.STYLE]: `STYLE`, + [PatchFlags.PROPS]: `PROPS`, + [PatchFlags.NEED_PATCH]: `NEED_PATCH`, + [PatchFlags.FULL_PROPS]: `FULL_PROPS`, + [PatchFlags.KEYED_V_FOR]: `KEYED_V_FOR`, + [PatchFlags.UNKEYED_V_FOR]: `UNKEYED_V_FOR`, + [PatchFlags.DYNAMIC_SLOTS]: `DYNAMIC_SLOTS` }