diff --git a/packages/compiler-dom/__tests__/transforms/vOn.spec.ts b/packages/compiler-dom/__tests__/transforms/vOn.spec.ts index 0ac528ea..20001b49 100644 --- a/packages/compiler-dom/__tests__/transforms/vOn.spec.ts +++ b/packages/compiler-dom/__tests__/transforms/vOn.spec.ts @@ -45,6 +45,32 @@ describe('compiler-dom: transform v-on', () => { }) }) + it('should support multiple events and modifiers options w/ prefixIdentifiers: true', () => { + const { props } = parseWithVOn( + `
`, + { + prefixIdentifiers: true + } + ) + const [clickProp, keyUpProp] = props + + expect(props).toHaveLength(2) + expect(clickProp).toMatchObject({ + type: NodeTypes.JS_PROPERTY, + value: { + callee: V_ON_WITH_MODIFIERS, + arguments: [{ content: '_ctx.test' }, '["stop"]'] + } + }) + expect(keyUpProp).toMatchObject({ + type: NodeTypes.JS_PROPERTY, + value: { + callee: V_ON_WITH_KEYS, + arguments: [{ content: '_ctx.test' }, '["enter"]'] + } + }) + }) + it('should support multiple modifiers and event options w/ prefixIdentifiers: true', () => { const { props: [prop] diff --git a/packages/compiler-dom/src/transforms/vOn.ts b/packages/compiler-dom/src/transforms/vOn.ts index 2fac2da3..8c4972e0 100644 --- a/packages/compiler-dom/src/transforms/vOn.ts +++ b/packages/compiler-dom/src/transforms/vOn.ts @@ -24,20 +24,46 @@ const isKeyboardEvent = /*#__PURE__*/ makeMap( true ) +const generateModifiers = (modifiers: string[]) => { + const keyModifiers = [] + const nonKeyModifiers = [] + const eventOptionModifiers = [] + + for (let i = 0; i < modifiers.length; i++) { + const modifier = modifiers[i] + + if (isEventOptionModifier(modifier)) { + // eventOptionModifiers: modifiers for addEventListener() options, e.g. .passive & .capture + eventOptionModifiers.push(modifier) + } else { + // runtimeModifiers: modifiers that needs runtime guards + if (isNonKeyModifier(modifier)) { + nonKeyModifiers.push(modifier) + } else { + keyModifiers.push(modifier) + } + } + } + + return { + keyModifiers, + nonKeyModifiers, + eventOptionModifiers + } +} + export const transformOn: DirectiveTransform = (dir, node, context) => { return baseTransform(dir, node, context, baseResult => { const { modifiers } = dir if (!modifiers.length) return baseResult let { key, value: handlerExp } = baseResult.props[0] + const { + keyModifiers, + nonKeyModifiers, + eventOptionModifiers + } = generateModifiers(modifiers) - // modifiers for addEventListener() options, e.g. .passive & .capture - const eventOptionModifiers = modifiers.filter(isEventOptionModifier) - // modifiers that needs runtime guards - const runtimeModifiers = modifiers.filter(m => !isEventOptionModifier(m)) - - // built-in modifiers that are not keys - const nonKeyModifiers = runtimeModifiers.filter(isNonKeyModifier) if (nonKeyModifiers.length) { handlerExp = createCallExpression(context.helper(V_ON_WITH_MODIFIERS), [ handlerExp, @@ -45,7 +71,6 @@ export const transformOn: DirectiveTransform = (dir, node, context) => { ]) } - const keyModifiers = runtimeModifiers.filter(m => !isNonKeyModifier(m)) if ( keyModifiers.length && // if event name is dynamic, always wrap with keys guard