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

Slot scope id refactor #3374

Merged
merged 6 commits into from
Mar 5, 2021
Merged

Slot scope id refactor #3374

merged 6 commits into from
Mar 5, 2021

Conversation

yyx990803
Copy link
Member

@yyx990803 yyx990803 commented Mar 5, 2021

This is a big refactor regarding SFC scoped ID for :slotted selectors. The original goal was to fix #2892, however in the process I realized the previous :slotted implementation was seriously flawed which led to this massive refactor. It does not contain any breaking behavior, however due to how substantial it is, it's submitted as a PR to explicitly document the internal changes.

  • Compiler-generated code for scope ID is in general simplified. Instead of generating a withId helper and wrapping every slot function with it, withCtx is now used in all cases. Tracking the slot's owner component also tracks its scope id so there no need to use different helpers anymore.

  • New slotted scope ID handling:

    • Compiler-generate slot outlets (i.e. <slot/>) now generate code that passes an additional boolean argument to renderSlot. This boolean argument indicates whether the current template belongs to an SFC that also has :slotted selectors.

    • When rendering the slot fragment, if the owner component uses :slotted, the fragment vnode gets assigned a slotScopeIds array.

    • In the patch phase, when encountering a fragment with non-null slotScopeIds, we now know this is a slot whose content needs the slotted scope attributes (data-v-xxxxxxxx-s).

    • This does require passing down slotScopeIds as an argument through almost all renderer functions, similar to isSVG and optimized. I did try refactoring it to a context instead, however the patch context refactor is very risky: it broke e2e test cases while passing all unit tests, and the end bundle size got bigger, so I ended up sticking with the argument passing.

    • SSR handling of scope ID is updated accordingly.

  • Optimization: slot scope IDs only need to be applied if the component actually uses :slotted styles.

    • @vue/compiler-dom and @vue/compiler-ssr now both accepted a slotted option. This option is true by default to retain backwards compatibility.
    • @vue/compiler-sfc
      • SFCDescriptor now exposes a slotted property which indicates whether the component uses :slotted styles.
      • compileTemplate now accepts a slotted option which is passed on to @vue/compiler-dom and @vue/compiler-ssr. Higher level tools (e.g. vite or vue-loader) should be updated to pass the descriptor's slotted property to compileTemplate to enable the optimization.

This is done by adding the `slotted: false` option to:

- compiler-dom
- compiler-ssr
- compiler-sfc (forwarded to template compiler)

At runtime, only slotted component will render slot fragments with
slot scope Ids. For SSR, only slotted component will add slot scope Ids
to rendered slot content. This should improve both runtime performance
and reduce SSR rendered markup size.

Note: requires SFC tooling (e.g. `vue-loader` and `vite`) to pass on
the `slotted` option from the SFC descriptoer to the `compileTemplate`
call.
@github-actions
Copy link

github-actions bot commented Mar 5, 2021

Size report

Path Size
vue.global.prod.js 40.89 KB (+0.35% 🔺)
runtime-dom.global.prod.js 27.16 KB (+0.3% 🔺)
size-check.global.prod.js 16.47 KB (+0.41% 🔺)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

use slotted() in component is not working when use transition element
1 participant