July 7, 2021
Custom Elements with Vue Reactivity
The 13th Hamburg Vue.js Meetup was held last week, this time as an online live-stream due to the ongoing COVID-19 restrictions. I was pleased to represent Factorial to share a talk on some insights on a small experiment in building Custom Elements with Vue 3.x’s standalone Reactivity module. Having previously worked with Vue’s own Custom Elements build option, I was keen to re-explore this topic with standalone Reactivity, also spurred on by Evan You’s ~70 lines-of-code experiment. My own question was, “could it really be that simple?”
Vue 3.x Reactivity
Vue’s Reactive utility (previously known as Vue.observable) has been heavily overhauled since the release of Vue 3 late in 2020. Its dependency to ES6 Proxy makes observing state changes a breeze for developers, but also means that Vue 3 drops support for Internet Explorer 11.
In practice, creating vanilla Custom Elements often involves writing lots of boilerplate code, especially when setting up reactive properties and observed attributes. This is something which is solved in some of the wide array of Custom Elements libraries and frameworks available. Addressing the issue of verbose boilerplate code is also an area where standalone Reactivity shines.
The “vue-micro” Experiment
My experiment in creating a framework to build Custom Elements borrows from Vue creator Evan You’s own proof of concept called vue-lit. The goals of my vue-uhtml (“vue-micro”) experiment were to:
- Add props validation
- Add a <slot> interface
- Implement some form of test coverage
The pseudo code below provides an overview of how the Custom Elements API is used to emulate the rendering and reactive features seen in Vue components.
View the actual code here.
Here’s an example of vue-uhtml in action combining reactive re-rendering on user input, props validation, and using a named <slot>.
I spent some time researching how Custom Elements could be test-automated. The community driven Open Web Components initiative provides a set of defaults, recommendations and tools to help facilitate web components projects. The @open-wc/testing package combines and configures testing libraries to quickly get up to speed writing tests for Custom Elements. The vue-uhtml repository includes tests for a Custom Element built with vue-uhtml covering lifecycle hooks, user input and props interfaces.
Take-aways and possible future
To conclude the talk, I shared my top three take-aways from this experiment with the Vue.js Hamburg:
- Standalone Vue Reactivity is pretty awesome
- Custom Elements are not scary
- More developers should also get out there and experiment
My learning experience through this process of experimenting with community driven open source software far outweighed the extent of checking off the original goals I had set out. I was encouraged on this point that the second talk of the evening by Thomas Jacob from sum.cumo (“VueGround: Ein Design-Tool und Playground für Vuetify, in Vuetify”) was also in the spirit of experimentation.
Writing user centric documentation and more comprehensive test coverage for vue-uhtml are two areas to focus on before vue-uhtml to be “production ready”. Whether vue-uhtml will be added to the wide selection of Custom Elements frameworks already available remains a question for the wider developer community to engage with.
Many thanks to Vue.js Hamburg and Joe Ray Gregory for organising this online Meetup, and to sum.cumo for the smooth hosting of the live-stream on YouTube. We are indeed looking forward to the day when in-person Vue.js Hamburg meetups will be possible again.
Senior Frontend Developer