]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(compiler-vapor): once modifier work with component event (#12606)
authoredison <daiwei521@126.com>
Wed, 8 Jan 2025 07:19:08 +0000 (15:19 +0800)
committerGitHub <noreply@github.com>
Wed, 8 Jan 2025 07:19:08 +0000 (15:19 +0800)
packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap
packages/compiler-vapor/__tests__/transforms/transformElement.spec.ts
packages/compiler-vapor/src/generators/prop.ts
packages/compiler-vapor/src/transform.ts
packages/compiler-vapor/src/transforms/vOn.ts
packages/runtime-vapor/src/componentEmits.ts

index adb34615cdff0ea0cece6dd5d71404e08a42196d..ff61d348d7112d63964d49438c40b5b5e5078d05 100644 (file)
@@ -212,6 +212,28 @@ export function render(_ctx) {
 }"
 `;
 
+exports[`compiler: element transform > component dynamic event with once modifier 1`] = `
+"import { resolveComponent as _resolveComponent, toHandlerKey as _toHandlerKey, createComponentWithFallback as _createComponentWithFallback } from 'vue';
+
+export function render(_ctx) {
+  const _component_Foo = _resolveComponent("Foo")
+  const n0 = _createComponentWithFallback(_component_Foo, { $: [
+    () => ({ [_toHandlerKey(_ctx.foo) + "Once"]: () => _ctx.bar })
+  ] }, null, true)
+  return n0
+}"
+`;
+
+exports[`compiler: element transform > component event with once modifier 1`] = `
+"import { resolveComponent as _resolveComponent, createComponentWithFallback as _createComponentWithFallback } from 'vue';
+
+export function render(_ctx) {
+  const _component_Foo = _resolveComponent("Foo")
+  const n0 = _createComponentWithFallback(_component_Foo, { onFooOnce: () => _ctx.bar }, null, true)
+  return n0
+}"
+`;
+
 exports[`compiler: element transform > component with dynamic event arguments 1`] = `
 "import { resolveComponent as _resolveComponent, toHandlerKey as _toHandlerKey, createComponentWithFallback as _createComponentWithFallback } from 'vue';
 
index b26f7c776f3a24e35526482041bc4da148545385..8afc73e4d368a63bf9d69efee9e65bff881b51e1 100644 (file)
@@ -940,6 +940,16 @@ describe('compiler: element transform', () => {
     ])
   })
 
+  test('component event with once modifier', () => {
+    const { code } = compileWithElementTransform(`<Foo @foo.once="bar" />`)
+    expect(code).toMatchSnapshot()
+  })
+
+  test('component dynamic event with once modifier', () => {
+    const { code } = compileWithElementTransform(`<Foo @[foo].once="bar" />`)
+    expect(code).toMatchSnapshot()
+  })
+
   test('invalid html nesting', () => {
     const { code, ir } = compileWithElementTransform(
       `<p><div>123</div></p>
index 46e85836baebf33faae54008f8fc171842b35a4b..62fca087ed73863fa5e2501e99902e9b7e3c45ef 100644 (file)
@@ -22,6 +22,7 @@ import {
 } from './utils'
 import {
   canSetValueDirectly,
+  capitalize,
   isSVGTag,
   shouldSetAsAttr,
   toHandlerKey,
@@ -108,15 +109,20 @@ function genLiteralObjectProps(
 }
 
 export function genPropKey(
-  { key: node, modifier, runtimeCamelize, handler }: IRProp,
+  { key: node, modifier, runtimeCamelize, handler, handlerModifiers }: IRProp,
   context: CodegenContext,
 ): CodeFragment[] {
   const { helper } = context
 
+  const handlerModifierPostfix = handlerModifiers
+    ? handlerModifiers.map(capitalize).join('')
+    : ''
   // static arg was transformed by v-bind transformer
   if (node.isStatic) {
     // only quote keys if necessary
-    const keyName = handler ? toHandlerKey(node.content) : node.content
+    const keyName =
+      (handler ? toHandlerKey(node.content) : node.content) +
+      handlerModifierPostfix
     return [
       [
         isSimpleIdentifier(keyName) ? keyName : JSON.stringify(keyName),
@@ -133,7 +139,15 @@ export function genPropKey(
   if (handler) {
     key = genCall(helper('toHandlerKey'), key)
   }
-  return ['[', modifier && `${JSON.stringify(modifier)} + `, ...key, ']']
+  return [
+    '[',
+    modifier && `${JSON.stringify(modifier)} + `,
+    ...key,
+    handlerModifierPostfix
+      ? ` + ${JSON.stringify(handlerModifierPostfix)}`
+      : undefined,
+    ']',
+  ]
 }
 
 export function genPropValue(
index bb4deb27cda32465c89758958cfc4fae23045e89..f8ff395ede5df9cc8d10655cef81a0c17c4adf4c 100644 (file)
@@ -47,6 +47,7 @@ export interface DirectiveTransformResult {
   modifier?: '.' | '^'
   runtimeCamelize?: boolean
   handler?: boolean
+  handlerModifiers?: string[]
   model?: boolean
   modelModifiers?: string[]
 }
index 6f04a0c1b24e26551b3e37893bf3c5c525d31b29..dd35dc14e572f3bb5bae4aec6f6721697d9375f3 100644 (file)
@@ -67,6 +67,7 @@ export const transformVOn: DirectiveTransform = (dir, node, context) => {
       key: arg,
       value: handler,
       handler: true,
+      handlerModifiers: eventOptionModifiers,
     }
   }
 
index f26c681350542008b41ce9594654b876cc1eded0..dc49ba6b1b5af602914ca05fd27a5a21e0b03ecc 100644 (file)
@@ -46,7 +46,7 @@ function propGetter(rawProps: Record<string, any>, key: string) {
     let i = dynamicSources.length
     while (i--) {
       const source = resolveSource(dynamicSources[i])
-      if (hasOwn(source, key)) return source[key]
+      if (hasOwn(source, key)) return resolveSource(source[key])
     }
   }
   return rawProps[key] && resolveSource(rawProps[key])