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])