]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(compiler-vapor): properly handle static ref in inline mode
authordaiwei <daiwei521@126.com>
Tue, 29 Apr 2025 07:26:53 +0000 (15:26 +0800)
committerdaiwei <daiwei521@126.com>
Tue, 29 Apr 2025 07:36:21 +0000 (15:36 +0800)
packages/compiler-vapor/__tests__/transforms/__snapshots__/transformTemplateRef.spec.ts.snap
packages/compiler-vapor/__tests__/transforms/transformTemplateRef.spec.ts
packages/compiler-vapor/src/generators/templateRef.ts

index f2eade4bcdf4e275f5a0b839ae9d762de1bb54a7..d823c4ed0af05444d7482e9c98b0facbe444c387 100644 (file)
@@ -43,6 +43,24 @@ export function render(_ctx) {
 }"
 `;
 
+exports[`compiler: template ref transform > static ref (PROD) 1`] = `
+"
+  const _setTemplateRef = _createTemplateRefSetter()
+  const n0 = t0()
+  _setTemplateRef(n0, foo)
+  return n0
+"
+`;
+
+exports[`compiler: template ref transform > static ref (inline mode) 1`] = `
+"
+  const _setTemplateRef = _createTemplateRefSetter()
+  const n0 = t0()
+  _setTemplateRef(n0, foo)
+  return n0
+"
+`;
+
 exports[`compiler: template ref transform > static ref 1`] = `
 "import { createTemplateRefSetter as _createTemplateRefSetter, template as _template } from 'vue';
 const t0 = _template("<div></div>", true)
index 6be8f18779cc777e9f966105bf24eead7668d08b..3dc9c80876b139d25737fd499d016058833830ff 100644 (file)
@@ -1,3 +1,4 @@
+import { BindingTypes } from '@vue/compiler-dom'
 import {
   DynamicFlag,
   type ForIRNode,
@@ -48,6 +49,16 @@ describe('compiler: template ref transform', () => {
     expect(code).contains('_setTemplateRef(n0, "foo")')
   })
 
+  test('static ref (inline mode)', () => {
+    const { code } = compileWithTransformRef(`<div ref="foo" />`, {
+      inline: true,
+      bindingMetadata: { foo: BindingTypes.SETUP_REF },
+    })
+    expect(code).matchSnapshot()
+    // pass the actual ref
+    expect(code).contains('_setTemplateRef(n0, foo)')
+  })
+
   test('dynamic ref', () => {
     const { ir, code } = compileWithTransformRef(`<div :ref="foo" />`)
 
index a4d6d546ed3007f2cda66a7909e2998e22a6bbfd..af8facc57b1f80b1342b16bb31ea8d192ef21e54 100644 (file)
@@ -2,6 +2,7 @@ import { genExpression } from './expression'
 import type { CodegenContext } from '../generate'
 import type { DeclareOldRefIRNode, SetTemplateRefIRNode } from '../ir'
 import { type CodeFragment, NEWLINE, genCall } from './utils'
+import { BindingTypes, type SimpleExpressionNode } from '@vue/compiler-dom'
 
 export const setTemplateRefIdent = `_setTemplateRef`
 
@@ -15,7 +16,7 @@ export function genSetTemplateRef(
     ...genCall(
       setTemplateRefIdent, // will be generated in root scope
       `n${oper.element}`,
-      genExpression(oper.value, context),
+      genRefValue(oper.value, context),
       oper.effect ? `r${oper.element}` : oper.refFor ? 'void 0' : undefined,
       oper.refFor && 'true',
     ),
@@ -25,3 +26,20 @@ export function genSetTemplateRef(
 export function genDeclareOldRef(oper: DeclareOldRefIRNode): CodeFragment[] {
   return [NEWLINE, `let r${oper.id}`]
 }
+
+function genRefValue(value: SimpleExpressionNode, context: CodegenContext) {
+  // in inline mode there is no setupState object, so we can't use string
+  // keys to set the ref. Instead, we need to transform it to pass the
+  // actual ref instead.
+  if (!__BROWSER__ && value && context.options.inline) {
+    const binding = context.options.bindingMetadata[value.content]
+    if (
+      binding === BindingTypes.SETUP_LET ||
+      binding === BindingTypes.SETUP_REF ||
+      binding === BindingTypes.SETUP_MAYBE_REF
+    ) {
+      return [value.content]
+    }
+  }
+  return genExpression(value, context)
+}