Let's talk about how to use Vue3 to build Web Components
How to build Web Components using Vue3? The following article will introduce you to the method of building Web Components with Vue3. I hope it will be helpful to you!
Sometimes I want to write a framework-independent component, but I don’t want to use native or Jquery to write it, and I also need to avoid style conflicts. It just feels right to use Web Components to do it. Quite appropriate. But now Web Components are still not flexible enough to use, and they are still inconvenient in many places. It would be great if they could be used in conjunction with MVVM. Angular has supported building components into Web Components long before. Vue3 3.2 finally supports building components into Web Components. I happened to want to reconstruct the comment plug-in recently, so I gave it a try.
Building Web Components
vue provides a defineCustomElement method to convert the vue component into a custom function construct that extends to HTMLElement The function and usage are basically the same as the defineComponent parameter API. [Related recommendations: vuejs video tutorial]
import { defineCustomElement } from 'vue' const MyVueElement = defineCustomElement({ // 在此提供正常的 Vue 组件选项 props: {}, emits: {}, template: `...`, // defineCustomElement 独有特性: CSS 会被注入到隐式根 (shadow root) 中 styles: [`/* inlined css */`] }) // 注册 Web Components customElements.define('my-vue-element', MyVueElement)
If you need to use a single file, you need @vitejs/plugin-vue@^1.4.0 or vue -loader@^16.5.0 or higher version tool. If only some files need to be used, you can change the suffix to .ce.vue. If you need to build all filesWeb Components, you can @vitejs/plugin-vue@^1.4.0 or vue-loader@^16.5.0 The customElement configuration item is enabled. This way you no longer need to use the .ce.vue suffix name.
Attributes
vue will map all the props to the properties of the custom element object, and also map the attributes on the custom element tags.
<com-demo></com-demo> props:{ type:String }
Because HTML's attribute can only be strings, except for basic types (Boolean, Number) Vue will help with type conversion during mapping, and other complex types need to be set to the DOM. on property.
Events
In custom elements, via this.$emit or in setup Events emitted by emit will be dispatched as native CustomEvents. Additional event parameters (payload) are exposed as an array on the details property of the CustomEvent object.
Slot
When writing components, you can use it like vue, but you can only use native slot syntax, so scope slots are no longer supported.
Sub-component style issues
When using nested sub-components, there is a pitfall in that the styles in the sub-components will not be extracted by default.
Parent component
<template> <div>{{ title }}</div> <childer></childer> </template> <script> import Childer from "./childer.vue" export default { components: { Childer }, data() { return { title: "父组件" } }, } </script> <style> .title { padding: 10px; background-color: #eee; font-weight: bold; } </style>
Subcomponent
<template> <div>{{ title }}</div> </template> <script> export default { data() { return { title: "子组件" } }, } </script> <style> .childer { padding: 10px; background-color: #222; color: #fff; font-weight: bold; } </style>
You can see that the style of the subcomponent is not inserted, but the style isolation identifier is generated data-v-5e87e937. I don’t know if Vue official will fix this bug in the future
If you look at the components, you can see that the styles of the sub-components have been extracted, so you only need to inject them yourself. .
Extract the sub-component style and insert it into the parent component, refer to this implementation
import ComDemo from '~/demo/index.vue' const deepStylesOf = ({ styles = [], components = {} }) => { const unique = array => [...new Set(array)]; return unique([...styles, ...Object.values(components).flatMap(deepStylesOf)]); } // 将子组件样式插入到父组件里 ComDemo.styles = deepStylesOf(ComDemo) !customElements.get('com-demo') && customElements.define('com-demo', defineCustomElement(ComDemo))
Perfectly solve the sub-component style problem
Method
defineCustomElement By default, the built component will not attach methods to customElement. Looking at the Vue source code, there are only _def (constructor), _instance (component instance)). If you want to call a method in the component, dom._instance.proxy.fun(), it feels really inelegant.
Of course we hope that the methods exposed by our components can be directly removed from dom.fun() like ordinary dom. We have slightly expanded defineCustomElement.
import { VueElement, defineComponent } from 'vue' const defineCustomElement = (options, hydate) => { const Comp = defineComponent(options); class VueCustomElement extends VueElement { constructor(initialProps) { super(Comp, initialProps, hydate); if (Comp.methods) { Object.keys(Comp.methods).forEach(key => { // 将所有非下划线开头方法 绑定到 元素上 if(!/^_/.test(key)){ this[key] = function (...res) { if (this._instance) { // 将方法thi改为 组件实例的proxy return Comp.methods[key].call(this._instance.proxy, ...res) } else { throw new Error('未找到组件实例') } } } }) } } } VueCustomElement.def = Comp; return VueCustomElement; }
Summary
Generally speaking, there are still a lot of pitfalls. If you only need to build some relatively simple cross-frame plug-ins, you can also use this method to build Web Components. A good solution.
For more programming-related knowledge, please visit: Introduction to Programming! !
The above is the detailed content of Let's talk about how to use Vue3 to build Web Components. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



There are three ways to refer to JS files in Vue.js: directly specify the path using the <script> tag;; dynamic import using the mounted() lifecycle hook; and importing through the Vuex state management library.

You can add a function to the Vue button by binding the button in the HTML template to a method. Define the method and write function logic in the Vue instance.

The watch option in Vue.js allows developers to listen for changes in specific data. When the data changes, watch triggers a callback function to perform update views or other tasks. Its configuration options include immediate, which specifies whether to execute a callback immediately, and deep, which specifies whether to recursively listen to changes to objects or arrays.

Using Bootstrap in Vue.js is divided into five steps: Install Bootstrap. Import Bootstrap in main.js. Use the Bootstrap component directly in the template. Optional: Custom style. Optional: Use plug-ins.

Implement marquee/text scrolling effects in Vue, using CSS animations or third-party libraries. This article introduces how to use CSS animation: create scroll text and wrap text with <div>. Define CSS animations and set overflow: hidden, width, and animation. Define keyframes, set transform: translateX() at the beginning and end of the animation. Adjust animation properties such as duration, scroll speed, and direction.

Vue.js has four methods to return to the previous page: $router.go(-1)$router.back() uses <router-link to="/" component window.history.back(), and the method selection depends on the scene.

You can query the Vue version by using Vue Devtools to view the Vue tab in the browser's console. Use npm to run the "npm list -g vue" command. Find the Vue item in the "dependencies" object of the package.json file. For Vue CLI projects, run the "vue --version" command. Check the version information in the <script> tag in the HTML file that refers to the Vue file.

There are three common methods for Vue.js to traverse arrays and objects: the v-for directive is used to traverse each element and render templates; the v-bind directive can be used with v-for to dynamically set attribute values for each element; and the .map method can convert array elements into new arrays.
