Web components and Vue

<custom-element /> + {{vue}} = ❤️

Text

Text

About me

  • A Nefelibata
  • JS Enthusiast
  • An Audiophile

Goofy's Story

He did it!

The problem

Vue components are limited within vue.js environment. Browser natively cannot understand vue components.

The solution

Vue components can be converted into custom elements which browsers can understand.

Why Web Components?

They are standardised technology, and are natively supported in modern browsers.

What are Web Components?

Web components are a set of web platform APIs that allow you to create new custom, reusable, encapsulated HTML tags

What are Web Components?

Web components are a set of web platform APIs that allow you to create new custom, reusable, encapsulated HTML tags

What are Web Components?

Web components are a set of web platform APIs that allow you to create new custom, reusable, encapsulated HTML tags

What are Web Components?

Web components are a set of web platform APIs that allow you to create new custom, reusable, encapsulated HTML tags

Web Components consist of four separate technologies that are used together

  1. Custom Elements

  2. Shadow DOM

  3. HTML Templates

  4. ES Module

What are Web Components?

Web Components consist of four separate technologies that are used together

  1. Custom Elements

  2. Shadow DOM

  3. HTML Templates

  4. ES Module

What are Web Components?

Web Components consist of four separate technologies that are used together

  1. Custom Elements

  2. Shadow DOM

  3. HTML Templates

  4. ES Module

What are Web Components?

Web Components consist of four separate technologies that are used together

  1. Custom Elements

  2. Shadow DOM

  3. HTML templates

  4. ES Module

What are Web Components?

Web Components consist of four separate technologies that are used together

  1. Custom Elements

  2. Shadow DOM

  3. HTML templates

  4. ES Module

What are Web Components?

Web Components in action

<script type="module" src="search_widget.js"></script>
...
<zcui-wc-search>
   #shadow-root (open)
	<style>
	...
	</style>
	<div class="zcui-wc-search">
	...
</zcui-wc-search>

@vue/web-component-wrapper

Wraps a Vue component as a web component / custom element. Vue Components can be imported as npm module and then it can be used accross vue project and it's custom elements can be used directly into the browser.

import Vue from 'vue'
import wrap from '@vue/web-component-wrapper'
import myElement from 'src/components/myelement'

const Component = {
  myElement
  // any component options
}

const CustomElement = wrap(Vue, Component)

window.customElements.define('my-element', CustomElement)

@vue/web-component-wrapper

Usage:


<meta charset="utf-8">
<title>my-element demo</title>
<script src="https://unpkg.com/vue"></script>
<script src="./my-element.js"></script>


<my-element msg="Hi, I am the production build."></my-element>

Interface Proxying:

Props:

 

All props declared in the Vue component are exposed on the custom element as its properties.

Events:

Custom events emitted on the inner Vue component are dispatched on the custom element as a CustomEvent

Slots:

Slots work the same way as expected, including named slots. Scoped slots however, are not supported as they are a Vue specific concept.

Build:

  "scripts": {
    "build": "vue-cli-service build --no-clean",
    "wc-build": "vue-cli-service build  --target wc --name wc-gallery ./src/components/wc-gallery.vue --no-clean"
  },
"vue-cli-service build  --target wc --name wc-gallery ./src/components/wc-gallery.vue --no-clean"

Build:

  "scripts": {
    "build": "vue-cli-service build --no-clean",
    "wc-build": "vue-cli-service build  --target wc --name wc-gallery ./src/components/wc-gallery.vue --no-clean"
  },

That's it!

Now you know how to convert your vue components to custom elements

DEMO

What about custom-elements?

🤔

If you already have custom elements they can be used within vue projects as well!

Web Components + vue

import Vue  from 'vue';
import VueRouter from 'vue-router';
import App from './main.vue'
import differenceInMinutes from 'date-fns/difference_in_minutes'

Vue.use(VueRouter);
Vue.config.ignoredElements = [
  'modify-search'
]

Search modification widget

Usage

<script  type="module" src="./zcui-search.js"></script>

/* project code here...
.
.
.
*/

<modify-search 
  host-name="https://www.zoomcar.com" 
  source-city="bangalore"
  destination-city="Mysuru"
  :source-location-name="sourceAddress"
  source-location-lat="12.9135218" 
  source-location-lng="77.5950804"
  :destination-location-name="destAddress"
  destination-location-lat="12.2958"
  destination-location-lng="76.6394"
  min-date-time="Thu Mar 30 2019 6:04:11"
  max-date-time="Thu Jun 30 2019 23:04:11" 
  :trip-start-date = "tripDetails.starts"
  :trip-end-date = "tripDetails.ends"
  @modifySearchSubmission="handleModifySearch"
  >
</modify-search>
/*
.
.
*/

Custom event handling:

custom events from custom element can be listened in similar manner we listen custom events for vue components 

Props:

Custom elements attributes and Vue components props are the same thing. The best part about using custom element within vur project is that Props will still be reactive.

Performance:

Vue Component

Web Component

Custom Element Best Practices:

1. Create a shadow root to encapsulate styles.

 

Custom Element Best Practices:

2. Create your shadow root in the constructor.

 

3. Place any children the element creates into its shadow root.

 

Custom Element Best Practices:

4. Do not override author-set, global attributes.

 

5. Aim to only accept rich data (objects, arrays) as properties.

 

 

Custom Element Best Practices:

6. Dispatch events in response to internal component activity.

 

7. Do not dispatch events in response to the host setting a property (downward data flow).

 

Web components are not perfect.

like any other technology web component has their own limitations.

  • Build System/Distribution
  • Boilerplating
  • Mapping between Properties and Attributes

Browser Support 

Browser Support 

Browser Support 

Browser Support 

Thanks !