简介
由 4 门技术结合起来的
- HTML Imports –> HTML Modules
- HTML Templates
- Custom Elements
- Shadow DOM
成熟的组件库特点:
实例
来看一组下面的实例,讲述了如何定义 web components 并获取 iframe 中的 web components
1 2 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>
|
1 2 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 元素
1 2 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
只要首字母不大写,大写是组件, 小写就是标签
1 2 3
| <fc-button> <TextView /> </fc-button>
|
Vue 中支持 WebCompents
在 vue.config.js 中
1 2 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 中
1 2 3 4 5 6 7 8 9 10 11 12
| export default defineConfig({ plugins: [ vue({ template: { compilerOptions: { isCustomElement: (tag) => tag.startsWith("fc-"), }, }, }), ], });
|