您好,欢迎来到年旅网。
搜索
您的当前位置:首页Web Components与Vue3

Web Components与Vue3

来源:年旅网

什么是webComponents

Web Components 是一种使用原生的js、html、css创建自定义组件的技术。相比于其他组件化框架,比如 Vue、React等,它具有体积小、不用加载其他外部模块的优势。

如何使用webComponents

class Btn extends HTMLElement {
    constructor () {
        super()
    }
}
  1. 使用 shandow DOM 将组件与外部隔离,防止组件内部样式影响到组件外元素的样式,然后使用原生 js 语法添加元素及样式:
class Btn extends HTMLElement {
    constructor () {
        super()
        // 使用 shadow Dom 将组件隔离,防止样式穿透
        const shadowDom = this.attachShadow({ mode: "open" })
        this.p = this.h('button')
        this.p.innerText = '自定义按钮'
        this.p.setAttribute('style', 'border: none; background-color: pink; height:30px;')
        shadowDom.appendChild(this.p)
    }
    h(el) {
        return document.createElement(el)
    }
}
  1. 使用 window.customElements.define() 注册自定义组件,根据规范,自定义组件的名称必须包含连词线,用与区别原生的 HTML 元素。
window.customElements.define('my-btn', Btn)
  1. 直接在html中使用:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>webComponents</title>
    <script src="./btn.js"></script>
</head>
<body>
    <my-btn></my-btn>
</body>
</html>

使用template 风格声明自定义组件

如果觉得上面的写法比较麻烦,我们可以使用template来声明自定义组件:
class templateBtn extends HTMLElement {
    constructor () {
        super()
        const shadowDom = this.attachShadow({ mode: "open" })

        this.template = this.h('template')
        this.template.innerHTML = `
            <button>自定义template风格按钮</button>
            <style>
                button{
                    border: none;
                    background-color: khaki;
                    height: 30px;
                    margin: 5px;
                    border-radius: 6px;
                }
            </style>
        `

        shadowDom.appendChild(this.template.content.cloneNode(true))
    }
    h(el) {
        return document.createElement(el)
    }
}

window.customElements.define('temp-btn', templateBtn)

Web Components 生命周期

web components 定义的组件有以下几个生命周期钩子:

// webComponents 生命周期
    // 挂载后
    connectedCallback () {
        console.log('挂载了');
    }
    // 断开后
    disconnectedCallback () {
        console.log('断开了');
    }
    // 被移动到新文档时
    adoptedCallback () {
        console.log('被移动了');
    }
    // 自定义元素的属性被增加、修改、删除时
    attributeChangedCallback () {
        console.log('属性改变了');
    }

自定义组件传递DOM属性

自定义组件可以像原生html元素那样使用 DOM attribute,由于 DOM attribute 只能为字符串类型的值,所以设置复杂类型的值时,需要使用 JSON.stringify() 将引用类型的值转为字符串,使用的时候再 JSON.parse() 转为引用类型。

<body>
    <my-btn></my-btn>
    <br>
    <temp-btn a="123"></temp-btn>
    <br>
    <button>原生btn</button>

    <script>
        const tempBtn = document.getElementsByTagName('temp-btn')[0]
        const a = {abc: 1}
        tempBtn.setAttribute('obj', JSON.stringify(a))
        const obj = tempBtn.getAttribute('obj')
        console.log(JSON.parse(obj).abc); // 1
    </script>
</body>

在Vue3中使用 Web Components

  1. 在 vite.config.ts 中进行配置:
import vue from '@vitejs/plugin-vue'
export default defineConfig({
  plugins: [
    vue({
      template: {
        compilerOptions: {
          isCustomElement: (tag:any) => tag.includes('my-')
        }
      }
    })
  ]
})
  1. 新建一个自定义组件,必须要以 .ce.vue 为后缀:
<template>
    <button>
        自定义按钮
    </button>
</template>

<script setup lang='ts'>
const props = defineProps<{
    obj: any
}>()
console.log(props.obj);
</script>

<style scoped>
button{
    height: 30px;
    background-color: skyblue;
    border: 1px solid #ccc;
    border-radius: 10px;
}
</style>
  1. 在父组件中引入,并使用vue 提供的 defineCustomElement 方法来创建自定义组件
<template>
  <div>
    <my-btn :obj="obj"></my-btn>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, defineCustomElement} from 'vue'
import customVueCeVue from './components/custom-vue.ce.vue'

const Btn = defineCustomElement(customVueCeVue)

window.customElements.define('my-btn', Btn)

const obj = {name: '张三'}

</script>

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- oldu.cn 版权所有 浙ICP备2024123271号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务