vue-hybrids
Hybrids web component wrappers for Vue components
vue-hybrids is an interop layer for Vue components and built on hybridsJS. Using vue-hybrids, you can quickly transition from building Vue single file components into pure web components with minimal interruptions to your toolchain.
Getting Started
Install npm package:
npm i --save-dev vue-hybrids
Then, import the vue-hybrids define
function into your SFC:
Finally, import the vue component to register it as a web component and use it in your appplication:
define
will wrap your component in a Hybrids JS web component, register it, and proxy all your props and events.
API
define
Define and register a new web component using an existing Vue component. Define returns the defn
argument.
definedefn: Object, options: DefineOptions: void
defn
A Vue component definition. Some special considerations around various options:
name
: This will be the name of the web component. By standard, web components must have a hyphen in their name.
options: DefineOptions
Various options for the component and/or component wrapper
-
vue?: Vue
An instance of the Vue constructor. This can be helpful for components which need to inherit functionality from plugins.
vue// the component has access to this.$store -
styles?: string | string[]
Style sheet strings for the shadowDOM. vue-hybrids will ensure that these styles do not bleed into the light DOM.
If you are using the typical vue-loader toolchain to bundle styles in conjunction with vue-hybrids, SFC <style>
tags will still be mounted in the light DOM and CSS selection into the shadow DOM will be restricted. Please avoid this in order to keep your web components side-effect free.
wrap
Wrap a vue component as a Hybrids component. The component can be defined later with a different name using the hybrids define
function.
// ... define'my-element-name', hybrid
Attributes
These attributes are available on all vue-hybrids components
vh-debug
A boolean prop which is available for every vue-hybrid which renders the proxied props, their type, and their value.
vh-key
A string key functioning much like key
in Vue. If the value of vh-key
changes, vue-hybrids will refresh the encapsulated Vue component.
This will execute all of its lifecycle methods again.
Design Considerations
Binding Prop Data
When passing props to vue-hybrids components from a vue component, you will need to pass props by property instead of by attribute. To do this, add the .prop
modifier to your props in vue templates.
- An issue with the
.prop
shorthand (.
) is documented here
Converting Vue Props
It's considered best practice to define types in your Vue component props. If no type is provided the wrapping hybrids component will assume a string, like other HTML attributes.
Vue Functionality
Avoid using the custom model
property of Vue component definitions. When wrapped as a web component,
the parent Vue component will not know to which event and prop it should bind v-model.
Instead, design your component to use the traditional value
prop and input
event if possible.
Or, if this is not possible, you may spell out the prop and event binding manually:
IE11
Though IE11 does not support the shadowDOM for style encapsulation, vue-hybrids should work with some polyfill support. Normally, one would include the following before any of their app code:
However, if you are using @babel/preset-env and/or core-js, you may have difficulty with overlapping polyfills.
vue-hybrids
provides a fix if your build falls into this scenario. Replace your @webcomponents import statement with:
If your polyfill implementation is more complicated, a manual fix can be employed by assigning a nonsense Symbol
before your @webcomponents import:
// Forces core-js to include their Symbol polyfill strictly before @webcomponentsconst nonce = Symbol'I_DO_NOTHING'
As a last resort, I've included a build of the @webcomponents/webcomponentsjs package which disincludes the Symbol polyfill. The package build outputs are generated from a fork (auzmartist/polyfills) and can be used like so:
Vue Dev Tools
vue-hybrids is compatible with vue dev tools. You can still inspect your mounted vue elements. Each defined component will show as wrapped in a <shadow-root>
tag to signify it's placement in the shadow DOM.
NOTE: If using vue-hybrids within another Vue app, Vue Dev Tools will tend to bind to your app Vue instance.
Development
Contributions welcome!
git clone git@github.com:auzmartist/vue-hybrids.git cd vue-hybrids npm install npm run dev