Description
EDIT 2022: Vue eventually got some support for creating Web Components, and the shortcomings of current situation is better described in this comment of mine below.
I'm opening this issue to start a high-level discussion about potential ways of integrating native Web Component with Vue.
Context
I'm interested in using native Web Components (WC) as an internal building block inside large Vue applications.
The following are interesting but not my focus here:
- Consuming 3rd-party WC;
- Building re-usable WC for 3rd-party to consume.
Why Web Components?
"Vue has its own component system, why do you want WC inside your app?"
The web platform is increasingly built with WC as a primitive for further features.
Well-known examples included Scoped Styles, without pre-processing tricks, true DOM encapsulation, or extending built-in elements.
More new-ish examples include Element Internals, which is a spec that lets you:
- associate your custom element with forms: link disable state to the enclosing form, support
:disabled
,:invalid
CSS states, take part in form validation, submission, reset, and more. - have default accessibility roles and states.
These can be pretty useful and I'd only expect more in the future.
Current limitations
Nothing prevents you from creating a WC in JS code.
As long as you configure Vue compiler to recognize the tag name isn't a Vue component, everything should work just fine.
IMHO where this is lacking is when it comes to integrating your WC implementation with the rest of your app.
Most likely, you'll want to implement the contents of your custom element using Vue itself, as you're already using it for the rest of the app.
Because there's a hard boundary at your custom element (your Vue app stops right here), you'd have to create a new Vue app instance for each custom element. This is a bit wasteful.
Worse, because it's 2 different apps, there's stuff that won't work at all, most notably injection (DI).
What Vue could provide
I think it would be interesting if Vue could optionally instantiate its component as custom elements and inject itself into them so that it flows seamlessly.
Imagine you could add customElement: true
to your component definition and Vue would:
- register a native Custom Element for that component;
- automatically pass itself in a hidden property so that the outer Vue context (esp. DI) would flow seamlessly into the custom element.
Then there's "comfort" APIs as, let's be honest, the native WC API are a pain to use. E.g. if props could optionally be reflected as attributes by Vue, if adding shadowDom: 'closed'
would do what it says, etc.
I wonder to what extend this would need core Vue support vs could be implemented in a user-land library.
I'm just throwing the idea here, there are a bunch of challenges/designs to address, e.g. how would this
representing the custom element surface in setup
, to be used in API such as attachInternals()
?
Thoughts?
Activity