Skip to content

JulienParis/vue-custom-element-buefy

Repository files navigation

VUE-CUSTOM-ELEMENT with BUEFY

This boilerplate project aims to use vue-custom-element library with Vue2, and use Buefy as a plugin/CSS framework, Material design fonts for the icons, all above encapsulating the CSS in every custom element's (or widget's) shadow DOM.

For test purposes we also created a shared vuex store between components, so a encapsulated widget could have an effect on anoter.

This project aimed to find an answer to this issue.

Notes

Why Vue2 ?

As we write this, Buefy is not supporting Vue3. So to make custom element using Buefy as a vue plugin we had to use Vue2, and vue-custom-element still seems the best way to make custom elements with vue2.

Inject CSS in shadow DOM

Due to the way vue-custom-element works the CSS must be imported and injected as strings in the custom-element options (shadowCss) in main.js. To do so we used the raw-loader library.

As the widgets are encapsulated in a shadow-root most of the buefy CSS only applies to the component. But still, some CSS selectors are by default set to inherit from the parents (when the style is something like box-sizing: inherit). To solve that problem we had to create a specific css file we also injected after injecting the buefy and material design css files (./src/styles/initialize.css).

Vue and scoped styles in shadow mode

In shadow mode the scoped styles usually used in Vue are useless : those styles are injected into the <head> tag, not reachable by the custom element within their shadow-root. To be able to apply different styles to specific components, even nested, we had to find a workaround : we created a mixin function available on all components (this.addStyle(url)) able to generate a <link> tag pointing to specific css files (in the public folder) from a value in component's data, and adding this link to the component's parent shadow-root.

Material Design fonts loading

By the same trick we can inject the Material Design CSS file, but doing so the injected css still needs to load the fonts themselves from a public folder (src: url("../fonts/materialdesignicons-webfont.eot") and so on).

/* From './node_modules/@mdi/font/css/materialdesignicons.css' file */

@font-face {
  font-family: "Material Design Icons";
  src: url("../fonts/materialdesignicons-webfont.eot?v=6.6.96");
  src: url("../fonts/materialdesignicons-webfont.eot?#iefix&v=6.6.96") format("embedded-opentype"), url("../fonts/materialdesignicons-webfont.woff2?v=6.6.96") format("woff2"), url("../fonts/materialdesignicons-webfont.woff?v=6.6.96") format("woff"), url("../fonts/materialdesignicons-webfont.ttf?v=6.6.96") format("truetype");
  font-weight: normal;
  font-style: normal;
}

To serve these fonts we need to copy the installed fonts from ./node_modules/@mdi/font/fonts folder to the ./public/fonts folder.

To automatize this operation we added a command at the beginning of the serve script :

// From './package.json'

{
  ...
  "scripts": {
    "serve": "cp -a ./node_modules/@mdi/font/fonts/. ./public/fonts && vue-cli-service serve",
    "build": "cp -a ./node_modules/@mdi/font/fonts/. ./public/fonts && vue-cli-service build",
    "test:unit": "vue-cli-service test:unit",
    "lint": "vue-cli-service lint"
  },
  ...
}

References


Running app Netlify Status

URL : https://test-vue-custom-element-with-buefy.netlify.app

Screenshot

screenshot


Project setup

The current project is working with npm 16.12.0 version

To install it, use the command :

nvm use
npm install

Compiles and hot-reloads for development

To run locally Datami you just have to type :

npm run serve

Compiles and minifies for production

npm run build

Run your unit tests

npm run test:unit

Lints and fixes files

npm run lint

About

Testing vue-custom-element with Buefy in shadow DOM

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published