From 1f911a57b1d5e95137d602fb21508959171ee273 Mon Sep 17 00:00:00 2001
From: daiwei
Date: Tue, 24 Dec 2024 21:22:12 +0800
Subject: [PATCH] fix(compiler-vapor): once modifier work with component event
---
.../transformElement.spec.ts.snap | 22 +++++++++++++++++++
.../transforms/transformElement.spec.ts | 10 +++++++++
.../compiler-vapor/src/generators/prop.ts | 20 ++++++++++++++---
packages/compiler-vapor/src/transform.ts | 1 +
packages/compiler-vapor/src/transforms/vOn.ts | 1 +
packages/runtime-vapor/src/componentEmits.ts | 2 +-
6 files changed, 52 insertions(+), 4 deletions(-)
diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap
index 1c37dad0f0d..e387eaa1691 100644
--- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap
+++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap
@@ -186,6 +186,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';
diff --git a/packages/compiler-vapor/__tests__/transforms/transformElement.spec.ts b/packages/compiler-vapor/__tests__/transforms/transformElement.spec.ts
index 030f32eea2b..a780457708a 100644
--- a/packages/compiler-vapor/__tests__/transforms/transformElement.spec.ts
+++ b/packages/compiler-vapor/__tests__/transforms/transformElement.spec.ts
@@ -872,6 +872,16 @@ describe('compiler: element transform', () => {
])
})
+ test('component event with once modifier', () => {
+ const { code } = compileWithElementTransform(``)
+ expect(code).toMatchSnapshot()
+ })
+
+ test('component dynamic event with once modifier', () => {
+ const { code } = compileWithElementTransform(``)
+ expect(code).toMatchSnapshot()
+ })
+
test('invalid html nesting', () => {
const { code, ir } = compileWithElementTransform(
`123
diff --git a/packages/compiler-vapor/src/generators/prop.ts b/packages/compiler-vapor/src/generators/prop.ts
index 46e85836bae..62fca087ed7 100644
--- a/packages/compiler-vapor/src/generators/prop.ts
+++ b/packages/compiler-vapor/src/generators/prop.ts
@@ -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(
diff --git a/packages/compiler-vapor/src/transform.ts b/packages/compiler-vapor/src/transform.ts
index 431054a6e43..2a55cf6e047 100644
--- a/packages/compiler-vapor/src/transform.ts
+++ b/packages/compiler-vapor/src/transform.ts
@@ -47,6 +47,7 @@ export interface DirectiveTransformResult {
modifier?: '.' | '^'
runtimeCamelize?: boolean
handler?: boolean
+ handlerModifiers?: string[]
model?: boolean
modelModifiers?: string[]
}
diff --git a/packages/compiler-vapor/src/transforms/vOn.ts b/packages/compiler-vapor/src/transforms/vOn.ts
index 6f04a0c1b24..dd35dc14e57 100644
--- a/packages/compiler-vapor/src/transforms/vOn.ts
+++ b/packages/compiler-vapor/src/transforms/vOn.ts
@@ -67,6 +67,7 @@ export const transformVOn: DirectiveTransform = (dir, node, context) => {
key: arg,
value: handler,
handler: true,
+ handlerModifiers: eventOptionModifiers,
}
}
diff --git a/packages/runtime-vapor/src/componentEmits.ts b/packages/runtime-vapor/src/componentEmits.ts
index f26c6813505..dc49ba6b1b5 100644
--- a/packages/runtime-vapor/src/componentEmits.ts
+++ b/packages/runtime-vapor/src/componentEmits.ts
@@ -46,7 +46,7 @@ function propGetter(rawProps: Record, 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])