Shadow DOM only
Closed this issue · 13 comments
Hello @EranGrin,
Thank you for creating this library. I think the main issue with Vue 3 WebComponents is their lack of support for normal DOM and just support of shadow DOM. It creates some issues with styling scopes, ex: not possible to use an external CSS stylesheet.
Does your library support both?
Best regards.
Hi There,
This isn't the first time I've come across this question, but I'm always curious, considering shadowDOM is one of the main features of web component encapsulation.
With that being said, I can add this feature, but it does feel like it's missing the entire point of web component usage.
I would be glad if someone could convince me otherwise
Hello @EranGrin,
Thanks for replying so fast.
It is an issue that I'm not the only one to have in my research: vuejs/core#4314 (comment) / vuejs/core#4404
So basically we use Vue in a monolith website. Most of the HTML is rendered by the backend and we use Vue to enhance the interactivity of the website.
The main issue is Vue always needs a root node for building an application. The workaround is to encapsulate the component as a WebComponent.
We have a common styling for the whole company (i.e. a CSS stylesheet coming through a CDN)
Imagine you have a .button
definition in this stylesheet, you cannot share the definition of a <button>
between a Vue component and the static content as the styles are isolated due to shadowDOM.
I had a look at the vue core code, it might be possible to override the attach shadow dom, but I'm not sure what will be the entire implications.
I can work on this next week, till then I'm on holiday
The main issue I've read so far is the impossibility of using slot
because it is part of the shadowDOM API.
That I would need to have in my use-case unfortunately...
I am not sure if you are aware of this, but CSS custom properties (variables) can penetrate the Shadow DOM
Yes I know, I'm refering to global CSS. The goal being not to have to rewrite all styles for the default button / headings / etc.
But maybe I'm taking the problem the wrong way.
@lbineau good news. I found a way to resolve the problem. It might take me a few days more to pack it and make some clean-ups. I spent a lot of time on this today, and I have to do some work that makes money as well.
The main issue was with the slots, as you mentioned before, this was painful to solve
@EranGrin Fantastic! What was the fix for you? Just a general description of it would be great
New Release 1.5.0 is live 🔥
Here is the demo of web component without shadow dom
https://stackblitz.com/~/github.com/EranGrin/web-component-no-shadow-dom-demo
First of all nice work @EranGrin, I checked your demo very cool! Would your Shadow Dom logic apply to this PR? vuejs/core#4404 - that would be a big win for the "reactivity sprinkling" use case that @lbineau described.
I admit I am in scenario where I'm building a Wordpress Theme and want to inject vue logic for certain e-commerce scenarios, and have had to create a process to bundle "web component" styles and import that specific stylesheet into the <style> of each vue component i use as a web component. This does lead to tailwind base classes being duplicated across all my shadow doms, it works, its just i'm adding about 50kb of inline css for each shadow dom I add, just to leverage tailwind. Being able to just use the main css file that the page as a whole uses would be ideal.
Hi @firescript,
I have doubt if vue core team will ever accept this PR as it's adding this strange path html-parsed-element.ts instead of the HTMLElement
for the base class,
We can work on another PR which introduces this feature in a more appropriate way, but there are several use-cases such as SSR and hydration which also part of the web component core api
,
However, this may take time for me to do it alone, as I don't really need it, and I'm quite busy.
Regarding your use case, you could also use the wrapper as is without shadow Dom.
If you wrap all the components with the plugin, you will also be able to solve your problem.
New Release 1.5.0 is live 🔥 Here is the demo of web component without shadow dom https://stackblitz.com/~/github.com/EranGrin/web-component-no-shadow-dom-demo
Thanks a lot for working on that topic, that's great news! I'll test it locally because the stackblitz link is failing to install error An unexpected error occurred: "too much recursion".
.
In the meantime, I've worked on a different approach by initializing Vue App inside a customElements.
customElements.define('vue-app', class extends HTMLElement {
app;
constructor() {
super();
if (this.dataset.vApp !== undefined) return
this.app = createApp(App})
}
connectedCallback () {
// Use in DOM root component template
// https://vuejs.org/guide/essentials/application.html#in-dom-root-component-template
this.app.mount(this)
}
disconnectedCallback () {
this.app.unmount()
this.app = null
}
})
The approach is very naive but at least it worked in my case.
I'm closing the issue because you implemented the solution.
@firescript
I add support to the SFC with nested component style and shadowDOM option, you can check the latest release