Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SFC compiler: optional chaining generates different event #4107

Closed
jods4 opened this issue Jul 12, 2021 · 1 comment
Closed

SFC compiler: optional chaining generates different event #4107

jods4 opened this issue Jul 12, 2021 · 1 comment
Labels
🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. has workaround A workaround has been found to avoid the problem 🐞 bug Something isn't working scope: compiler scope: sfc

Comments

@jods4
Copy link
Contributor

jods4 commented Jul 12, 2021

Version

3.1.4

Reproduction link

https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHRlbXBsYXRlPlxuICA8ZGl2IEBjbGljaz1cImEuYlwiPkNsaWNrICh3b3Jrcyk8L2Rpdj5cbiAgPGRpdiBAY2xpY2s9XCJhPy5iXCI+Q2xpY2sgKGJyb2tlbik8L2Rpdj5cbjwvdGVtcGxhdGU+XG5cbjxzY3JpcHQgc2V0dXA+XG5jb25zdCBhID0ge1xuICBiKCkgeyBhbGVydChcIndvcmtzXCIpIH1cbn1cbjwvc2NyaXB0PiJ9

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.

@posva posva added 🐞 bug Something isn't working 🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. has workaround A workaround has been found to avoid the problem scope: compiler labels Jul 12, 2021
@lidlanca
Copy link
Contributor

lidlanca commented Jul 13, 2021

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"

@github-actions github-actions bot locked and limited conversation to collaborators Oct 16, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. has workaround A workaround has been found to avoid the problem 🐞 bug Something isn't working scope: compiler scope: sfc
Projects
None yet
Development

No branches or pull requests

4 participants