SFC compiler: optional chaining generates different event
Version
3.1.4
Reproduction link
Steps to reproduce
Click on the repro divs, one works, the other doesn't.
The reason why is evident if you look at the generated JS code.
SFC compiler handles event listeners that are an expression, such as a.b
, as functions themselves and invokes (...args) => a.b && a.b(args)
It does not consider a?.b
to be such an expression, though, and invokes () => a?.b
.
What is expected?
Both works
What is actually happening?
Only first link works
You could take this opportunity to optimise generated code a.b && a.b(...args)
into a.b?.(...args)
.
Not only is the latter shorter, it also evaluates the first part only once, which might be relevant if there are side-effects -- and one common side-effect is reactivity tracking, so it's just more performant.
Downside: if targeting a browser that doesn't support optional chaining, the code needs to be transpiled. With evergreen broswers, everybody supports it nowadays (Chrome 80, FF 74, Safari 13.1): https://caniuse.com/mdn-javascript_operators_optional_chaining
PS: The issue creation app replaces +
with
everywhere, including in the repro link and that breaks links to sfc.vuejs.org.
source:
transformOn
const isMemberExp = isMemberExpression(exp.content);
a?.b
evals to false, that is where the logic differ compared to the a.b
expression.
also isMemberExpression
is used to check for assignability of an expression, and optional chaining is not assignable.
that is not the best fit check for: is an invokable expression or an "optional chained member expression"