core icon indicating copy to clipboard operation
core copied to clipboard

fix(custom-element): enhance slot handling with `shadowRoot:false`

Open edison1105 opened this issue 8 months ago • 9 comments

close #13206 close #13234

Note This PR only fixed bugs in the optimized mode, while issues still exist in the full diff scenario. This happens because _renderSlots only renders slots that have corresponding outlets, meaning not all slots in this._slots are rendered to the DOM tree. During full diff, parent.insertBefore(node, anchor) throws an error because the anchor node isn't actually in the DOM tree.

I couldn't find a suitable solution, so rolled back the full diff related code in 3e724095072d6ae4f8b095e6fc0eb25eb1564f67

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features
    • Enhanced support for Vue custom elements without Shadow DOM, improving slot fallback content management and dynamic slot updates.
  • Bug Fixes
    • Fixed element mounting and slot updating issues for custom elements with shadowRoot: false, ensuring correct DOM insertion and slot rendering.
  • Tests
    • Added extensive tests covering slot updates, fallback content, and conditional rendering in custom elements without Shadow DOM for improved stability.

edison1105 avatar Apr 16 '25 03:04 edison1105

Size Report

Bundles

File Size Gzip Brotli
runtime-dom.global.prod.js 102 kB (+1.45 kB) 38.6 kB (+412 B) 34.8 kB (+358 B)
vue.global.prod.js 160 kB (+1.45 kB) 58.8 kB (+404 B) 52.3 kB (+378 B)

Usages

Name Size Gzip Brotli
createApp (CAPI only) 46.6 kB (+74 B) 18.2 kB (+38 B) 16.7 kB (+31 B)
createApp 54.6 kB (+74 B) 21.2 kB (+39 B) 19.4 kB (+41 B)
createSSRApp 58.8 kB (+74 B) 23 kB (+34 B) 21 kB (+40 B)
defineCustomElement 60.7 kB (+1.45 kB) 23.2 kB (+426 B) 21.1 kB (+338 B)
overall 68.6 kB (+74 B) 26.4 kB (+41 B) 24 kB (+41 B)

github-actions[bot] avatar Apr 16 '25 03:04 github-actions[bot]

Open in StackBlitz

@vue/compiler-core

npm i https://pkg.pr.new/@vue/compiler-core@13208
@vue/compiler-dom

npm i https://pkg.pr.new/@vue/compiler-dom@13208
@vue/compiler-sfc

npm i https://pkg.pr.new/@vue/compiler-sfc@13208
@vue/compiler-ssr

npm i https://pkg.pr.new/@vue/compiler-ssr@13208
@vue/runtime-core

npm i https://pkg.pr.new/@vue/runtime-core@13208
@vue/reactivity

npm i https://pkg.pr.new/@vue/reactivity@13208
@vue/runtime-dom

npm i https://pkg.pr.new/@vue/runtime-dom@13208
@vue/server-renderer

npm i https://pkg.pr.new/@vue/server-renderer@13208
@vue/shared

npm i https://pkg.pr.new/@vue/shared@13208
vue

npm i https://pkg.pr.new/vue@13208
@vue/compat

npm i https://pkg.pr.new/@vue/compat@13208

commit: 3e72409

pkg-pr-new[bot] avatar Apr 16 '25 03:04 pkg-pr-new[bot]

Hi @edison1105, thanks for this fix, it works well with Vue 3.

However it doesn't work if we create custom elements from Vue 3 components and use them in Vue 2 or React wrapping with Vue 2 or React component similarly as I did in reproduction playground (see CEWrapperOne) . To provide more context: here is a schema of what we are working on at the moment. So we are creating a component library based on Vue 3 but to reuse this implementation in different applications written in Vue 2 or React we use custom elements created from Vue 3 components implementation.

image

wolandec avatar Apr 17 '25 08:04 wolandec

@wolandec I also found some issues in other scenarios and haven't found a good solution yet, so the PR is still in Draft status.

edison1105 avatar Apr 18 '25 02:04 edison1105

@edison1105 thanks for the clarification, I'll prepare a reproduction repo for our case if it helps.

wolandec avatar Apr 18 '25 06:04 wolandec

@edison1105 https://github.com/wolandec/vue-core-issue-13206 Here is the repository with the reproduction of our case of using, I hope it helps. Please let me know if you need any help, thank you!

wolandec avatar Apr 18 '25 21:04 wolandec

"""

Walkthrough

The changes introduce enhanced support for Vue custom elements using shadowRoot: false, focusing on correct slot and conditional rendering behavior. Core renderer logic, slot parsing, and DOM patching are updated, and new tests are added to verify slot fallback and v-if/v-show handling in custom elements without shadow DOM.

Changes

File(s) Change Summary
packages/runtime-core/src/renderer.ts Modified element mounting and patching logic to handle Vue custom elements with shadowRoot: false, including container reassignment, slot updates via _updateSlots, and fallback handling in patchBlockChildren.
packages/runtime-dom/src/apiCustomElement.ts Enhanced slot management for custom elements without shadow DOM: introduced _slotFallbacks, _slotAnchors, and modified _slots properties; added _updateSlots, _parseSlotFallbacks methods; improved fallback slot capturing and rendering; adjusted slot parsing to retain parent references; added helpers for DOM insertion and node collection; updated cleanup in disconnectedCallback.
packages/runtime-dom/tests/customElement.spec.ts Added tests for custom elements with shadowRoot: false to verify correct slot fallback, conditional rendering (v-if), and slot content switching, both with optimized and standard rendering modes. No changes to existing logic.

Sequence Diagram(s)

sequenceDiagram
    participant Host as Host App
    participant VueCE as Vue Custom Element (shadowRoot: false)
    participant Renderer as Renderer
    participant DOM as DOM

    Host->>VueCE: Insert slotted content (with v-if/v-show)
    VueCE->>Renderer: Mount element
    Renderer->>VueCE: Call _parseSlotFallbacks and _renderSlots
    VueCE->>DOM: Insert anchor and slot/fallback content
    Host->>VueCE: Update reactive state (e.g., v-if toggles)
    VueCE->>Renderer: Patch element
    Renderer->>VueCE: Call _updateSlots (oldVNode, newVNode)
    VueCE->>DOM: Update slot content or fallback as needed

Assessment against linked issues

Objective Addressed Explanation
Correctly render and update slotted content with v-if/v-show in custom elements ( #13206 )
Prevent errors and ensure named slot content with v-if works without exceptions ( #13234 )

Poem

In the garden of slots, where the shadows don’t grow,
The v-if and v-show now shimmer and glow.
Fallbacks and anchors, a bunny’s delight,
No more null errors in the custom element night!
🐇✨
Hop-hop—slots fixed just right! """

[!TIP]

⚡️ Faster reviews with caching
  • CodeRabbit now supports caching for code and dependencies, helping speed up reviews. This means quicker feedback, reduced wait times, and a smoother review experience overall. Cached data is encrypted and stored securely. This feature will be automatically enabled for all accounts on May 16th. To opt out, configure Review - Disable Cache at either the organization or repository level. If you prefer to disable all data retention across your organization, simply turn off the Data Retention setting under your Organization Settings.

Enjoy the performance boost—your workflow just got faster.

✨ Finishing Touches
  • [ ] 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

coderabbitai[bot] avatar May 08 '25 03:05 coderabbitai[bot]

/ecosystem-ci run

edison1105 avatar May 10 '25 14:05 edison1105

📝 Ran ecosystem CI: Open

suite result latest scheduled
language-tools :white_check_mark: success :white_check_mark: success
pinia :white_check_mark: success :white_check_mark: success
radix-vue :white_check_mark: success :white_check_mark: success
primevue :white_check_mark: success :white_check_mark: success
vite-plugin-vue :white_check_mark: success :white_check_mark: success
nuxt :white_check_mark: success :white_check_mark: success
test-utils :white_check_mark: success :white_check_mark: success
quasar :white_check_mark: success :white_check_mark: success
vitepress :white_check_mark: success :white_check_mark: success
vuetify :white_check_mark: success :white_check_mark: success
vue-simple-compiler :white_check_mark: success :white_check_mark: success
vue-macros :white_check_mark: success :white_check_mark: success
vant :white_check_mark: success :white_check_mark: success
vueuse :white_check_mark: success :white_check_mark: success
vue-i18n :white_check_mark: success :white_check_mark: success
router :white_check_mark: success :white_check_mark: success

vue-bot avatar May 10 '25 14:05 vue-bot