export function render(_ctx) {
const n0 = t0()
- _delegate(n0, "click", () => _ctx.a['b' + _ctx.c])
+ _delegate(n0, "click", e => _ctx.a['b' + _ctx.c](e))
return n0
}"
`;
const n0 = t0()
_renderEffect(() => {
- _on(n0, _ctx.event, () => _ctx.handler, {
+ _on(n0, _ctx.event, e => _ctx.handler(e), {
effect: true
})
})
const n0 = t0()
_renderEffect(() => {
- _on(n0, _ctx.event(_ctx.foo), () => _ctx.handler, {
+ _on(n0, _ctx.event(_ctx.foo), e => _ctx.handler(e), {
effect: true
})
})
const n0 = t0()
_renderEffect(() => {
- _on(n0, _ctx.event, () => _ctx.handler, {
+ _on(n0, _ctx.event, e => _ctx.handler(e), {
effect: true
})
})
const n19 = t3()
const n20 = t3()
const n21 = t3()
- _delegate(n0, "click", () => _withModifiers(_ctx.handleEvent, ["stop"]))
- _on(n1, "submit", () => _withModifiers(_ctx.handleEvent, ["prevent"]))
- _delegate(n2, "click", () => _withModifiers(_ctx.handleEvent, ["stop","prevent"]))
- _delegate(n3, "click", () => _withModifiers(_ctx.handleEvent, ["self"]))
- _on(n4, "click", () => _ctx.handleEvent, {
+ _delegate(n0, "click", _withModifiers(_ctx.handleEvent, ["stop"]))
+ _on(n1, "submit", _withModifiers(_ctx.handleEvent, ["prevent"]))
+ _delegate(n2, "click", _withModifiers(_ctx.handleEvent, ["stop","prevent"]))
+ _delegate(n3, "click", _withModifiers(_ctx.handleEvent, ["self"]))
+ _on(n4, "click", _ctx.handleEvent, {
capture: true
})
- _on(n5, "click", () => _ctx.handleEvent, {
+ _on(n5, "click", _ctx.handleEvent, {
once: true
})
- _on(n6, "scroll", () => _ctx.handleEvent, {
+ _on(n6, "scroll", _ctx.handleEvent, {
passive: true
})
- _delegate(n7, "contextmenu", () => _withModifiers(_ctx.handleEvent, ["right"]))
- _delegate(n8, "click", () => _withModifiers(_ctx.handleEvent, ["left"]))
- _delegate(n9, "mouseup", () => _withModifiers(_ctx.handleEvent, ["middle"]))
- _delegate(n10, "contextmenu", () => _withKeys(_withModifiers(_ctx.handleEvent, ["right"]), ["enter"]))
- _delegate(n11, "keyup", () => _withKeys(_ctx.handleEvent, ["enter"]))
- _delegate(n12, "keyup", () => _withKeys(_ctx.handleEvent, ["tab"]))
- _delegate(n13, "keyup", () => _withKeys(_ctx.handleEvent, ["delete"]))
- _delegate(n14, "keyup", () => _withKeys(_ctx.handleEvent, ["esc"]))
- _delegate(n15, "keyup", () => _withKeys(_ctx.handleEvent, ["space"]))
- _delegate(n16, "keyup", () => _withKeys(_ctx.handleEvent, ["up"]))
- _delegate(n17, "keyup", () => _withKeys(_ctx.handleEvent, ["down"]))
- _delegate(n18, "keyup", () => _withKeys(_ctx.handleEvent, ["left"]))
- _delegate(n19, "keyup", () => _withModifiers(_ctx.submit, ["middle"]))
- _delegate(n20, "keyup", () => _withModifiers(_ctx.submit, ["middle","self"]))
- _delegate(n21, "keyup", () => _withKeys(_withModifiers(_ctx.handleEvent, ["self"]), ["enter"]))
+ _delegate(n7, "contextmenu", _withModifiers(_ctx.handleEvent, ["right"]))
+ _delegate(n8, "click", _withModifiers(_ctx.handleEvent, ["left"]))
+ _delegate(n9, "mouseup", _withModifiers(_ctx.handleEvent, ["middle"]))
+ _delegate(n10, "contextmenu", _withKeys(_withModifiers(_ctx.handleEvent, ["right"]), ["enter"]))
+ _delegate(n11, "keyup", _withKeys(_ctx.handleEvent, ["enter"]))
+ _delegate(n12, "keyup", _withKeys(_ctx.handleEvent, ["tab"]))
+ _delegate(n13, "keyup", _withKeys(_ctx.handleEvent, ["delete"]))
+ _delegate(n14, "keyup", _withKeys(_ctx.handleEvent, ["esc"]))
+ _delegate(n15, "keyup", _withKeys(_ctx.handleEvent, ["space"]))
+ _delegate(n16, "keyup", _withKeys(_ctx.handleEvent, ["up"]))
+ _delegate(n17, "keyup", _withKeys(_ctx.handleEvent, ["down"]))
+ _delegate(n18, "keyup", _withKeys(_ctx.handleEvent, ["left"]))
+ _delegate(n19, "keyup", _withModifiers(e => _ctx.submit(e), ["middle"]))
+ _delegate(n20, "keyup", _withModifiers(e => _ctx.submit(e), ["middle","self"]))
+ _delegate(n21, "keyup", _withKeys(_withModifiers(_ctx.handleEvent, ["self"]), ["enter"]))
return [n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15, n16, n17, n18, n19, n20, n21]
}"
`;
export function render(_ctx) {
const n0 = t0()
- _delegate(n0, "click", () => e => _ctx.foo(e))
+ _delegate(n0, "click", e => _ctx.foo(e))
return n0
}"
`;
export function render(_ctx) {
const n0 = t0()
- _delegate(n0, "click", () => $event => (_ctx.foo($event)))
+ _delegate(n0, "click", $event => (_ctx.foo($event)))
return n0
}"
`;
export function render(_ctx) {
const n0 = t0()
- _delegate(n0, "click", () => $event => {_ctx.foo($event);_ctx.bar()})
+ _delegate(n0, "click", $event => {_ctx.foo($event);_ctx.bar()})
return n0
}"
`;
export function render(_ctx) {
const n0 = t0()
- _delegate(n0, "click", () => $event => {_ctx.i++;_ctx.foo($event)})
+ _delegate(n0, "click", $event => {_ctx.i++;_ctx.foo($event)})
return n0
}"
`;
export function render(_ctx) {
const n0 = t0()
- _delegate(n0, "click", () => (e: any): any => _ctx.foo(e))
+ _delegate(n0, "click", (e: any): any => _ctx.foo(e))
return n0
}"
`;
export function render(_ctx) {
const n0 = t0()
- _delegate(n0, "click", () =>
+ _delegate(n0, "click",
$event => {
_ctx.foo($event)
}
export function render(_ctx) {
const n0 = t0()
- _delegate(n0, "click", () => $event => _ctx.foo($event))
+ _delegate(n0, "click", $event => _ctx.foo($event))
return n0
}"
`;
export function render(_ctx) {
const n0 = t0()
- _delegate(n0, "click", () => _ctx.a['b' + _ctx.c])
+ _delegate(n0, "click", e => _ctx.a['b' + _ctx.c](e))
return n0
}"
`;
export function render(_ctx) {
const n0 = t0()
- _delegate(n0, "click", () => _ctx.test)
+ _delegate(n0, "click", e => _ctx.test(e))
return n0
}"
`;
export function render(_ctx) {
const n0 = t0()
- _delegate(n0, "click", () => $event => {
+ _delegate(n0, "click", () => {
_ctx.foo();
_ctx.bar()
})
export function render(_ctx) {
const n0 = t0()
- _delegate(n0, "click", () => $event => {_ctx.foo();_ctx.bar()})
+ _delegate(n0, "click", () => {_ctx.foo();_ctx.bar()})
return n0
}"
`;
export function render(_ctx) {
const n0 = t0()
- _delegate(n0, "click", () => _ctx.foo.bar)
+ _delegate(n0, "click", e => _ctx.foo.bar(e))
return n0
}"
`;
export function render(_ctx) {
const n0 = t0()
- _delegate(n0, "keyup", () => _withModifiers(_ctx.test, ["exact"]))
+ _delegate(n0, "keyup", _withModifiers(e => _ctx.test(e), ["exact"]))
return n0
}"
`;
export function render(_ctx) {
const n0 = t0()
- _delegate(n0, "click", () => _withModifiers(_ctx.test, ["stop"]))
- _delegate(n0, "keyup", () => _withKeys(_ctx.test, ["enter"]))
+ _delegate(n0, "click", _withModifiers(e => _ctx.test(e), ["stop"]))
+ _delegate(n0, "keyup", _withKeys(e => _ctx.test(e), ["enter"]))
return n0
}"
`;
export function render(_ctx) {
const n0 = t0()
- _on(n0, "click", () => _withModifiers(_ctx.test, ["stop","prevent"]), {
+ _on(n0, "click", _withModifiers(e => _ctx.test(e), ["stop","prevent"]), {
capture: true,
once: true
})
export function render(_ctx) {
const n0 = t0()
- _delegate(n0, "mouseup", () => _withModifiers(_ctx.test, ["middle"]))
+ _delegate(n0, "mouseup", _withModifiers(e => _ctx.test(e), ["middle"]))
return n0
}"
`;
const n0 = t0()
_renderEffect(() => {
- _on(n0, (_ctx.event) === "click" ? "mouseup" : (_ctx.event), () => _withModifiers(_ctx.test, ["middle"]), {
+ _on(n0, (_ctx.event) === "click" ? "mouseup" : (_ctx.event), _withModifiers(e => _ctx.test(e), ["middle"]), {
effect: true
})
})
export function render(_ctx) {
const n0 = t0()
- _delegate(n0, "contextmenu", () => _withModifiers(_ctx.test, ["right"]))
+ _delegate(n0, "contextmenu", _withModifiers(e => _ctx.test(e), ["right"]))
return n0
}"
`;
const n0 = t0()
_renderEffect(() => {
- _on(n0, (_ctx.event) === "click" ? "contextmenu" : (_ctx.event), () => _withKeys(_withModifiers(_ctx.test, ["right"]), ["right"]), {
+ _on(n0, (_ctx.event) === "click" ? "contextmenu" : (_ctx.event), _withKeys(_withModifiers(e => _ctx.test(e), ["right"]), ["right"]), {
effect: true
})
})
export function render(_ctx) {
const n0 = t0()
- _delegate(n0, "click", () => $event => (_ctx.i++))
+ _delegate(n0, "click", () => (_ctx.i++))
return n0
}"
`;
const n0 = t0()
_renderEffect(() => {
- _on(n0, _ctx.e, () => _withKeys(_withModifiers(_ctx.test, ["left"]), ["left"]), {
+ _on(n0, _ctx.e, _withKeys(_withModifiers(e => _ctx.test(e), ["left"]), ["left"]), {
effect: true
})
})
const n0 = t0()
const n1 = t0()
const n2 = t0()
- _delegate(n0, "click", () => $event => (x.value=_unref(y)))
- _delegate(n1, "click", () => $event => (x.value++))
- _delegate(n2, "click", () => $event => ({ x: x.value } = _unref(y)))
+ _delegate(n0, "click", () => (x.value=_unref(y)))
+ _delegate(n1, "click", () => (x.value++))
+ _delegate(n2, "click", () => ({ x: x.value } = _unref(y)))
return [n0, n1, n2]
"
`;
export function render(_ctx) {
const n0 = t0()
- _on(n0, "keydown", () => _withKeys(_withModifiers(_ctx.test, ["stop","ctrl"]), ["a"]), {
+ _on(n0, "keydown", _withKeys(_withModifiers(e => _ctx.test(e), ["stop","ctrl"]), ["a"]), {
capture: true
})
return n0
export function render(_ctx) {
const n0 = t0()
- _delegate(n0, "keyup", () => _withKeys(_ctx.test, ["left"]))
+ _delegate(n0, "keyup", _withKeys(e => _ctx.test(e), ["left"]))
return n0
}"
`;
export function render(_ctx, $props, $emit, $attrs, $slots) {
const n0 = t0()
- _delegate(n0, "click", () => _ctx.handleClick)
+ _delegate(n0, "click", _ctx.handleClick)
return n0
}"
`;
delegate: true,
},
])
- expect(code).contains(`_delegate(n0, "click", () => $event => (_ctx.i++))`)
+ expect(code).contains(`_delegate(n0, "click", () => (_ctx.i++))`)
})
test('should wrap in unref if identifier is setup-maybe-ref w/ inline: true', () => {
)
expect(code).matchSnapshot()
expect(helpers).contains('unref')
+ expect(code).contains(`_delegate(n0, "click", () => (x.value=_unref(y)))`)
+ expect(code).contains(`_delegate(n1, "click", () => (x.value++))`)
expect(code).contains(
- `_delegate(n0, "click", () => $event => (x.value=_unref(y)))`,
- )
- expect(code).contains(`_delegate(n1, "click", () => $event => (x.value++))`)
- expect(code).contains(
- `_delegate(n2, "click", () => $event => ({ x: x.value } = _unref(y)))`,
+ `_delegate(n2, "click", () => ({ x: x.value } = _unref(y)))`,
)
})
// in this case the return value is discarded and the behavior is
// consistent with 2.x
expect(code).contains(
- `_delegate(n0, "click", () => $event => {_ctx.foo();_ctx.bar()})`,
+ `_delegate(n0, "click", () => {_ctx.foo();_ctx.bar()})`,
)
})
// in this case the return value is discarded and the behavior is
// consistent with 2.x
expect(code).contains(
- `_delegate(n0, "click", () => $event => {\n_ctx.foo();\n_ctx.bar()\n})`,
+ `_delegate(n0, "click", () => {\n_ctx.foo();\n_ctx.bar()\n})`,
)
})
])
// should NOT prefix $event
expect(code).contains(
- `_delegate(n0, "click", () => $event => (_ctx.foo($event)))`,
+ `_delegate(n0, "click", $event => (_ctx.foo($event)))`,
)
})
])
// should NOT prefix $event
expect(code).contains(
- `_delegate(n0, "click", () => $event => {_ctx.foo($event);_ctx.bar()})`,
+ `_delegate(n0, "click", $event => {_ctx.foo($event);_ctx.bar()})`,
)
})
value: { content: '$event => foo($event)' },
},
])
- expect(code).contains(
- `_delegate(n0, "click", () => $event => _ctx.foo($event))`,
- )
+ expect(code).contains(`_delegate(n0, "click", $event => _ctx.foo($event))`)
})
test('should NOT wrap as function if expression is already function expression (with Typescript)', () => {
},
])
expect(code).contains(
- `_delegate(n0, "click", () => (e: any): any => _ctx.foo(e))`,
+ `_delegate(n0, "click", (e: any): any => _ctx.foo(e))`,
)
})
])
expect(code).matchSnapshot()
- expect(code).contains(`_delegate(n0, "click", () => _ctx.a['b' + _ctx.c])`)
+ expect(code).contains(
+ `_delegate(n0, "click", e => _ctx.a['b' + _ctx.c](e))`,
+ )
})
test('function expression w/ prefixIdentifiers: true', () => {
value: { content: `e => foo(e)` },
},
])
- expect(code).contains(`_delegate(n0, "click", () => e => _ctx.foo(e))`)
+ expect(code).contains(`_delegate(n0, "click", e => _ctx.foo(e))`)
})
test('should error if no expression AND no modifier', () => {
},
])
expect(code).contains(
- `_on(n0, "click", () => _withModifiers(_ctx.test, ["stop","prevent"]), {
+ `_on(n0, "click", _withModifiers(e => _ctx.test(e), ["stop","prevent"]), {
capture: true,
once: true
})`,
expect(code).matchSnapshot()
expect(code).contains(
- `_delegate(n0, "click", () => _withModifiers(_ctx.test, ["stop"]))
- _delegate(n0, "keyup", () => _withKeys(_ctx.test, ["enter"]))`,
+ `_delegate(n0, "click", _withModifiers(e => _ctx.test(e), ["stop"]))
+ _delegate(n0, "keyup", _withKeys(e => _ctx.test(e), ["enter"]))`,
)
})
})
expect(code).matchSnapshot()
- expect(code).contains(`_delegate(n0, "click", () => _ctx.foo.bar)`)
+ expect(code).contains(`_delegate(n0, "click", e => _ctx.foo.bar(e))`)
})
test('should delegate event', () => {
import {
+ BindingTypes,
type SimpleExpressionNode,
isFnExpression,
isMemberExpression,
nonKeys: string[]
keys: string[]
} = { nonKeys: [], keys: [] },
- needWrap: boolean = true,
+ // passed as component prop - need additional wrap
+ extraWrap: boolean = false,
): CodeFragment[] {
let handlerExp: CodeFragment[] = [`() => {}`]
if (value && value.content.trim()) {
- const isMemberExp = isMemberExpression(value, context.options)
- const isInlineStatement = !(
- isMemberExp || isFnExpression(value, context.options)
- )
-
- if (isInlineStatement) {
- const expr = context.withId(() => genExpression(value, context), {
- $event: null,
- })
+ // Determine how the handler should be wrapped so it always reference the
+ // latest value when invoked.
+ if (isMemberExpression(value, context.options)) {
+ // e.g. @click="foo.bar"
+ handlerExp = genExpression(value, context)
+ if (!isConstantBinding(value, context) && !extraWrap) {
+ // non constant, wrap with invocation as `e => foo.bar(e)`
+ // when passing as component handler, access is always dynamic so we
+ // can skip this
+ handlerExp = [`e => `, ...handlerExp, `(e)`]
+ }
+ } else if (isFnExpression(value, context.options)) {
+ // Fn expression: @click="e => foo(e)"
+ // no need to wrap in this case
+ handlerExp = genExpression(value, context)
+ } else {
+ // inline statement
+ // @click="foo($event)" ---> $event => foo($event)
+ const referencesEvent = value.content.includes('$event')
const hasMultipleStatements = value.content.includes(`;`)
+ const expr = referencesEvent
+ ? context.withId(() => genExpression(value, context), {
+ $event: null,
+ })
+ : genExpression(value, context)
handlerExp = [
- '$event => ',
+ referencesEvent ? '$event => ' : '() => ',
hasMultipleStatements ? '{' : '(',
...expr,
hasMultipleStatements ? '}' : ')',
]
- } else {
- handlerExp = [...genExpression(value, context)]
}
}
handlerExp = genWithModifiers(context, handlerExp, nonKeys)
if (keys.length) handlerExp = genWithKeys(context, handlerExp, keys)
- if (needWrap) handlerExp.unshift(`() => `)
+ if (extraWrap) handlerExp.unshift(`() => `)
return handlerExp
}
): CodeFragment[] {
return genCall(context.helper('withKeys'), handler, JSON.stringify(keys))
}
+
+function isConstantBinding(
+ value: SimpleExpressionNode,
+ context: CodegenContext,
+) {
+ if (value.ast === null) {
+ const bindingType = context.options.bindingMetadata[value.content]
+ if (bindingType === BindingTypes.SETUP_CONST) {
+ return true
+ }
+ }
+}