简介
由 4 门技术结合起来的
- HTML Imports –> HTML Modules
- HTML Templates
- Custom Elements
- Shadow DOM
成熟的组件库特点:
实例
来看一组下面的实例,讲述了如何定义 web components 并获取 iframe 中的 web components
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 
 | <!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>Document</title>
 </head>
 <body>
 <h1>开启服务才能获取 iframe 内容</h1>
 <iframe src="./iframe.html"></iframe>
 <fs-components></fs-components>
 <script>
 customElements.define(
 "fs-components",
 class extends HTMLElement {
 constructor() {
 super();
 
 console.log("先运行构造函数");
 }
 connectedCallback() {
 
 console.log("再运行连接回调");
 }
 disconnectedCallback() {
 
 console.log("当删除组件时才会运行失联回调");
 }
 adoptedCallback() {
 document.adoptNode();
 alert("被导入");
 
 
 console.log("当使用 document.adoptNode 后会运行收养回调");
 }
 attributeChangedCallback(name, oldValue, newValue) {
 
 }
 }
 );
 
 const iframe = document.querySelector("iframe");
 
 const selfComponent = document.querySelector("fs-components");
 document.body.appendChild(document.adoptNode(selfComponent));
 
 iframe.onload = () => {
 const webComponent =
 iframe.contentDocument.querySelector("fancy-components");
 document.body.appendChild(document.adoptNode(webComponent));
 };
 </script>
 </body>
 </html>
 
 | 
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 
 | <!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>If</title>
 </head>
 <body>
 <fancy-components></fancy-components>
 <script>
 customElements.define(
 "fancy-components",
 class extends HTMLElement {
 constructor() {
 super();
 
 console.log("先运行构造函数");
 }
 connectedCallback() {
 
 console.log("再运行连接回调");
 }
 disconnectedCallback() {
 
 console.log("当删除组件时才会运行失联回调");
 }
 adoptedCallback() {
 alert("iframe内 fancy-components 被导入");
 
 
 console.log("当使用 document.adoptNode 后会运行收养回调");
 }
 }
 );
 </script>
 </body>
 </html>
 
 | 
也可以继承 HTML 元素
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 
 | customElements.define("our-input",
 class extends HTMLInputElement {
 constructor() {
 super();
 
 this.placeholder = "属于我们的输入框!";
 this.disabled = true;
 }
 
 },
 { extends: "input" }
 );
 
 | 
相信从以上案例,已经能初步了解 web components 的用法,更多用途在网络上有更丰富的案例
组件库
CSS-Doodle
基于 web components 开发的组件库,(炫酷效果的组件库,日常开发中用不到)
css-doodle
fancy-components
花式组件库, 在日常开发中用得到
fancy-components
在框架中使用
React 支持 WebComponents
只要首字母不大写,大写是组件, 小写就是标签
| 12
 3
 
 | <fc-button><TextView />
 </fc-button>
 
 | 
Vue 中支持 WebCompents
在 vue.config.js 中
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 
 | module.exports = {chainWebpack: (config) => {
 config.module
 .rule("vue")
 .use("vue-loader")
 .tap((options) => {
 
 options.compilerOptions = {
 ...(options.compilerOptions || {}),
 isCustomElement: (tag) => tag.startsWith("fc-"),
 };
 
 return options;
 });
 },
 };
 
 | 
vite 中使用 WebCompents
在 vite.config.js 中
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 
 | export default defineConfig({
 plugins: [
 vue({
 template: {
 compilerOptions: {
 isCustomElement: (tag) => tag.startsWith("fc-"),
 },
 },
 }),
 ],
 });
 
 |