diff --git a/packages/compiler-core/__tests__/transforms/__snapshots__/cacheStatic.spec.ts.snap b/packages/compiler-core/__tests__/transforms/__snapshots__/cacheStatic.spec.ts.snap index 375a0c8674a..6f40f568166 100644 --- a/packages/compiler-core/__tests__/transforms/__snapshots__/cacheStatic.spec.ts.snap +++ b/packages/compiler-core/__tests__/transforms/__snapshots__/cacheStatic.spec.ts.snap @@ -217,7 +217,7 @@ return function render(_ctx, _cache) { return (_openBlock(), _createElementBlock("div", null, [ _withDirectives((_openBlock(), _createElementBlock("svg", null, _cache[0] || (_cache[0] = [ _createElementVNode("path", { d: "M2,3H5.5L12" }, null, -1 /* HOISTED */) - ]))), [ + ]), 512 /* NEED_PATCH */)), [ [_directive_foo] ]) ])) diff --git a/packages/compiler-core/__tests__/transforms/__snapshots__/transformText.spec.ts.snap b/packages/compiler-core/__tests__/transforms/__snapshots__/transformText.spec.ts.snap index 7fb49ea7887..55a7d714325 100644 --- a/packages/compiler-core/__tests__/transforms/__snapshots__/transformText.spec.ts.snap +++ b/packages/compiler-core/__tests__/transforms/__snapshots__/transformText.spec.ts.snap @@ -73,7 +73,7 @@ return function render(_ctx, _cache) { return _withDirectives((_openBlock(), _createElementBlock("p", null, [ _createTextVNode(_toDisplayString(foo), 1 /* TEXT */) - ])), [ + ], 512 /* NEED_PATCH */)), [ [_directive_foo] ]) } diff --git a/packages/compiler-core/__tests__/transforms/transformElement.spec.ts b/packages/compiler-core/__tests__/transforms/transformElement.spec.ts index bf3510a052d..12f4a74552a 100644 --- a/packages/compiler-core/__tests__/transforms/transformElement.spec.ts +++ b/packages/compiler-core/__tests__/transforms/transformElement.spec.ts @@ -1028,6 +1028,46 @@ describe('compiler: element transform', () => { expect(node.patchFlag).toBe(PatchFlags.NEED_PATCH) }) + test('NEED_PATCH (vFor + static ref)', () => { + const { node } = parseWithBind( + `
`, + ) + expect(node.patchFlag).toBe(PatchFlags.NEED_PATCH) + }) + + test('NEED_PATCH (vFor + custom directives)', () => { + const { node } = parseWithBind( + `
`, + ) + expect(node.patchFlag).toBe(PatchFlags.NEED_PATCH) + }) + + test('NEED_PATCH (vFor + vnode hooks)', () => { + const root = baseCompile( + `
`, + { + prefixIdentifiers: true, + cacheHandlers: true, + }, + ).ast + const node = (root as any).children[0].children[0].codegenNode + expect(node.patchFlag).toBe(PatchFlags.NEED_PATCH) + }) + + test('NEED_PATCH (vFor + setRef function)', () => { + const root = baseCompile( + `
`, + { + prefixIdentifiers: true, + bindingMetadata: { + setRefFn: BindingTypes.SETUP_CONST, + }, + }, + ).ast + const node = (root as any).children[0].children[0].codegenNode + expect(node.patchFlag).toBe(PatchFlags.NEED_PATCH) + }) + test('script setup inline mode template ref (binding exists)', () => { const { node } = parseWithElementTransform(``, { inline: true, diff --git a/packages/compiler-core/src/transforms/transformElement.ts b/packages/compiler-core/src/transforms/transformElement.ts index 76ca1d44353..53059efd84f 100644 --- a/packages/compiler-core/src/transforms/transformElement.ts +++ b/packages/compiler-core/src/transforms/transformElement.ts @@ -456,9 +456,12 @@ export function buildProps( value.type === NodeTypes.JS_CACHE_EXPRESSION || ((value.type === NodeTypes.SIMPLE_EXPRESSION || value.type === NodeTypes.COMPOUND_EXPRESSION) && - getConstantType(value, context) > 0) + getConstantType(value, context) > 0 && + name !== 'ref') ) { - // skip if the prop is a cached handler or has constant value + // skip if: + // 1. the prop is a cached handler + // 2. has constant value (excluding :ref="setRefFn", setRefFn is a setup-const) return } @@ -738,7 +741,6 @@ export function buildProps( } } if ( - !shouldUseBlock && (patchFlag === 0 || patchFlag === PatchFlags.NEED_HYDRATION) && (hasRef || hasVnodeHook || runtimeDirectives.length > 0) ) {