一、webcomponets介绍
在Vue 3中使用Web Components可以通过多种方式实现。Web Components是一组允许你创建可重用、封装良好的自定义元素的标准技术。它们包括Custom Elements、Shadow DOM、HTML Templates等。
Vue3 支持原生模式,可以让单个文件的js,css,html以html为界限的局部环境中,不影响到全局,组件之间也不会相互影响。
封装原生的webcomponents,由三部分组成的。
1、Custom elements(自定义元素)
JavaScriptAPI,允许定义custom elements及其行为,然后可以在我们的用户界面中按照需要使用它们。
2、Shadow Dom(影子Dom)
JavaScriptAPI,用于将封装的“影子”DOM树附加到元素(与主文档DOM分开呈现)并控制其关联的功能。通过这种方式,开发者可以保持元素的功能私有,这样它们就可以被脚本化和样式化,而不用担心与文档的其他部分发生冲突。
3、HTML templates(Html模版)
和元素使开发者可以编写与HTML结构类似的组件和样式。然后它们可以作为自定义元素结构的基础被多次重用。
二、原生webcomponets开发实例
编辑组件
btn.js
第一种用法 基本方法
class Btn extends HTMLElement{constructor(){//初始化类的实例,必须调用父类构造函数。super(); //在子类中用于调用父类的构造函数,确保父类的初始化逻辑正常执行。//编写自己的功能const shaDom = this.attachShadow({mode:"open"})this.p = this.h('p') //相当于 this.p = document.createElement('p')this.p.innerText = '绿曼巴'this.p.setAttribute('style','width:200px; height:200px;border:1px solid black')shaDom.appendChild(this.p)}h(el){return document.createElement(el)}
}
// 挂载
window.customElements.define('lmb-btn',Btn) //有四个生命周期//当自定义元素第一次被连接到文档 DOM 时被调用。connectedCallback() {console.log('我已经插入了')}//当自定义元素与文档 DOM 断开连接时被调用。disconnectedCallback() {console.log('我已经断开了')}//当自定义元素被移动到新文档时被调用adoptedCallback() {console.log('我被移动了')}//当自定义元素的一个属性被增加、移除或更改时被调用attributeChangedCallback() {console.log('我被改变了')}
第二种用法 使用template模版
class Btn extends HTMLElement{constructor(){//初始化类的实例,必须调用父类构造函数。super(); //在子类中用于调用父类的构造函数,确保父类的初始化逻辑正常执行。//编写自己的功能const shaDom = this.attachShadow({mode:"open"})this.template = this.h('template') this.template.innerHTML = `<!--这里的样式只局限在这里使用,和外界隔离--><style>div{width:200px;height:200px;border:1px solid black;}</style><div>绿曼巴1</div>`shaDom.appendChild(this.template.content.cloneNode(true))}h(el){return document.createElement(el)}
}
// 挂载
window.customElements.define('lmb-btn',Btn)
使用组件
<lmb-btn></lmb-btn>
三、在vue3中使用原生组件
1、在vite.config.ts 进行配置
import { fileURLToPath, URL } from 'node:url'import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'// https://vite.dev/config/
export default defineConfig({plugins: [vue({//----------------------------增加部分--------------------------------template:{compilerOptions:{//去匹配lmb-开头的都会跳过组件的检测,把它识别成CustomElement//要开启这个模式,只需要将你的组件文件以 .ce.vue 结尾即可isCustomElement:(tag)=>tag.includes('lmb-')}}//----------------------------增加部分结束-------------------------------}),vueJsx(),],resolve: {alias: {'@': fileURLToPath(new URL('./src', import.meta.url))}}
})
2、创建并引入组件
建立文件:src/components/custom-vue.ce.vue
在App.vue 中
<template><div><!--传递参数 如果是对象需要JSON.stringify序列化--><lmb-btn :obj="JSON.stringify(obj)"></lmb-btn></div>
</template>
<script setup lang='ts'>
import { ref,reactive,defineCustomElement } from 'vue'
import customVueCe from './components/custom-vue.ce.vue';
/*
用于将 Vue 组件转换为自定义元素(Web Components),
从而能够在非 Vue 环境中使用。它让 Vue 组件直接注册为浏览器原生的自定义 HTML 元素,
使其可以在任何前端项目中以自定义标签的方式使用。
1、跨框架兼容性:转换后的自定义元素不依赖 Vue 框架,因此可以在各种框架中自由使用。
2、组件隔离:Web Components(自定义元素)具有 Shadow DOM 隔离特性,样式和功能不会影响页面中的其他元素,适合独立封装和复用。
3、数据传递和事件监听:转换后的组件仍然可以使用 props 和 emit 来接受数据和传递事件,适用于复杂交互的组件。
*/
const Btn = defineCustomElement(customVueCe)
//注册自定义元素
window.customElements.define('lmb-btn',Btn)
const obj = {name:"zhangsan"}
</script>
3、custom-vue.ce.vue(自定义元素必须以.ce.vue结尾)
<template><div>lvmanba {{obj}}</div>
</template>
<script setup lang='ts'>
import { ref,reactive } from 'vue'
defineProps<{obj:any
}>()
</script>
传递的参数,会自动添加到标签上。