Table of Contents
Building Web Components
Attributes
Events
Slot
Sub-component style issues
Method
Summary
Home Web Front-end Vue.js Let's talk about how to use Vue3 to build Web Components

Let's talk about how to use Vue3 to build Web Components

Sep 08, 2022 pm 08:20 PM
vue vue3

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!

Let's talk about how to use Vue3 to build Web Components

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)
Copy after login

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
}
Copy after login

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>
Copy after login

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>
Copy after login

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

Lets talk about how to use Vue3 to build Web Components
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. .

Lets talk about how to use Vue3 to build Web Components

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))
Copy after login

Perfectly solve the sub-component style problem

Lets talk about how to use Vue3 to build Web Components

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.
Lets talk about how to use Vue3 to build Web Components
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;
}
Copy after login

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!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: How To Unlock Everything In MyRise
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

How to reference js file with vue.js How to reference js file with vue.js Apr 07, 2025 pm 11:27 PM

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

How to add functions to buttons for vue How to add functions to buttons for vue Apr 08, 2025 am 08:51 AM

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.

How to use watch in vue How to use watch in vue Apr 07, 2025 pm 11:36 PM

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.

How to use bootstrap in vue How to use bootstrap in vue Apr 07, 2025 pm 11:33 PM

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.

Vue realizes marquee/text scrolling effect Vue realizes marquee/text scrolling effect Apr 07, 2025 pm 10:51 PM

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 &lt;div&gt;. 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.

How to return to previous page by vue How to return to previous page by vue Apr 07, 2025 pm 11:30 PM

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

How to query the version of vue How to query the version of vue Apr 07, 2025 pm 11:24 PM

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 &lt;script&gt; tag in the HTML file that refers to the Vue file.

How to use vue traversal How to use vue traversal Apr 07, 2025 pm 11:48 PM

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.

See all articles