Web Components与Vue3

什么是webComponents

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

如何使用webComponents

  1. 自定义组件都是由类声明的,我们需要先定义一个类:
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>

在这里插入图片描述
更多详细用法请查看 Vue 官网: Vue 与 Web Components

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue 2和Vue 3在组件封装方面有一些区别。下面是一些主要的区别: 1. 语法:Vue 2使用的是Options API,而Vue 3引入了Composition API。Options API基于选项对象,在一个对象中定义组件的选项,但随着组件变得复杂,选项对象可能会变得冗长。Composition API允许开发者通过函数的形式来组织组件的逻辑,使代码更易维护和重用。 2. 组件注册:在Vue 2中,我们使用Vue.component()全局注册组件或者通过components选项在局部注册组件。而在Vue 3中,全局注册的方法变成了app.component(),而且不再需要通过Vue实例来进行注册。 3. Props 的类型声明:在Vue 2中,我们需要使用props选项来声明组件的Props,并可以指定各个prop的类型、默认值等信息。而在Vue 3中,可以使用`<script setup>`语法来声明Props并给它指定类型。 4. 生命周期钩子:在Vue 2中,我们使用各种生命周期钩子函数来处理组件的生命周期事件。而在Vue 3中,Options API中的生命周期钩子函数仍然可用,但推荐使用Composition API中的函数式API来处理。 5. Transition/动画:Vue 2中有内置的transition和动画系统,可以通过<transition>和<transition-group>标签来实现。而在Vue 3中,这些功能被迁移到了单独的@vue/transition和@vue/animation库中,需要额外安装和引入。 需要注意的是,Vue 3在组件封装方面引入了更多的改进,并且提供了更强大和灵活的开发体验。但由于Vue 3相对于Vue 2来说还比较新,一些库和插件可能还没有完全适配Vue 3,因此在升级之前需要考虑项目的具体情况和可行性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值