From 4ecc656b441a27ad967e5eafa5b4f7ffb05df382 Mon Sep 17 00:00:00 2001 From: Doctor Wu Date: Thu, 11 Apr 2024 18:12:03 +0800 Subject: [PATCH] feat(compiler-vapor, runtime-vapor): support listen sub components emit related #4 --- .../src/generators/component.ts | 6 ++--- packages/compiler-vapor/src/transform.ts | 1 + packages/compiler-vapor/src/transforms/vOn.ts | 23 ++++++++++++++++++- packages/runtime-vapor/src/componentEmits.ts | 15 ++++++++---- 4 files changed, 37 insertions(+), 8 deletions(-) diff --git a/packages/compiler-vapor/src/generators/component.ts b/packages/compiler-vapor/src/generators/component.ts index af7482db2..8f7113dad 100644 --- a/packages/compiler-vapor/src/generators/component.ts +++ b/packages/compiler-vapor/src/generators/component.ts @@ -63,9 +63,9 @@ export function genCreateComponent( ...props.map(prop => { return [ ...genPropKey(prop, context), - ': () => (', - ...genExpression(prop.values[0], context), - ')', + ...(prop.applyRawValue + ? [': ', prop.values[0].content, ','] + : [': () => (', ...genExpression(prop.values[0], context), ')']), ] }), ) diff --git a/packages/compiler-vapor/src/transform.ts b/packages/compiler-vapor/src/transform.ts index 7a693f785..ce7e93d59 100644 --- a/packages/compiler-vapor/src/transform.ts +++ b/packages/compiler-vapor/src/transform.ts @@ -41,6 +41,7 @@ export type DirectiveTransform = ( export interface DirectiveTransformResult { key: SimpleExpressionNode value: SimpleExpressionNode + applyRawValue?: boolean modifier?: '.' | '^' runtimeCamelize?: boolean } diff --git a/packages/compiler-vapor/src/transforms/vOn.ts b/packages/compiler-vapor/src/transforms/vOn.ts index d758754ed..e2d2ba70c 100644 --- a/packages/compiler-vapor/src/transforms/vOn.ts +++ b/packages/compiler-vapor/src/transforms/vOn.ts @@ -1,9 +1,15 @@ -import { ErrorCodes, createCompilerError } from '@vue/compiler-dom' +import { + ElementTypes, + ErrorCodes, + createCompilerError, + createSimpleExpression, +} from '@vue/compiler-dom' import type { DirectiveTransform } from '../transform' import { IRNodeTypes, type KeyOverride, type SetEventIRNode } from '../ir' import { resolveModifiers } from '@vue/compiler-dom' import { extend, makeMap } from '@vue/shared' import { resolveExpression } from '../utils' +import { EMPTY_EXPRESSION } from './utils' const delegatedEvents = /*#__PURE__*/ makeMap( 'beforeinput,click,dblclick,contextmenu,focusin,focusout,input,keydown,' + @@ -14,6 +20,8 @@ const delegatedEvents = /*#__PURE__*/ makeMap( export const transformVOn: DirectiveTransform = (dir, node, context) => { let { arg, exp, loc, modifiers } = dir + const isComponent = node.tagType === ElementTypes.COMPONENT + if (!exp && (!modifiers.length || !arg)) { context.options.onError( createCompilerError(ErrorCodes.X_V_ON_NO_EXPRESSION, loc), @@ -70,6 +78,19 @@ export const transformVOn: DirectiveTransform = (dir, node, context) => { } } + if (isComponent) { + const eventName = arg.content + const handler = exp || EMPTY_EXPRESSION + return { + key: createSimpleExpression(eventName, true, arg.loc), + value: extend(handler, { + isHandler: true, + loc: handler.loc, + }), + applyRawValue: true, + } + } + const operation: SetEventIRNode = { type: IRNodeTypes.SET_EVENT, element: context.reference(), diff --git a/packages/runtime-vapor/src/componentEmits.ts b/packages/runtime-vapor/src/componentEmits.ts index bbca2044c..002c5d78c 100644 --- a/packages/runtime-vapor/src/componentEmits.ts +++ b/packages/runtime-vapor/src/componentEmits.ts @@ -74,10 +74,17 @@ export function emit( // TODO: warn let handlerName - let handler = - rawProps[(handlerName = toHandlerKey(event))] || - // also try camelCase event handler (#2249) - rawProps[(handlerName = toHandlerKey(camelize(event)))] + let handler + for (let rawProp of rawProps) { + if ( + (handler = + rawProp[(handlerName = toHandlerKey(event))] || + // also try camelCase event handler (#2249) + rawProp[(handlerName = toHandlerKey(camelize(event)))]) + ) { + break + } + } // for v-model update:xxx events, also trigger kebab-case equivalent // for props passed via kebab-case if (!handler && isModelListener) {