Web Components允许用户自定义一个html元素 来实现组件化开发、进行复用,
利用该技术我们封装实现特定功能特定样式的定制元素用在我们想使用的任何地方
目前主流框架几乎都支持该技术
- vue 通过Vue CLI3和新的@vue/web-component-wrapper库创建web components十分方便
- react 可以自由选择在 Web Components 中使用 React,或者在 React 中使用 Web Components,或者两者共存
通过customElements.define()方法用来注册一个 custom element,该方法接受以下参数
-
表示所创建的元素名称的符合 DOMString 标准的字符串。注意,custom element 的名称不能是单个单词,且其中必须有段划线。
-
用于定义元素行为的类(自定义类) 。
-
可选参数
,一个包含extends
属性的配置对象,是可选参数。它指定了所创建的元素继承自哪个内置元素,可以继承任何内置元素。 -
例如 window.customElements.define('web-com',webCom)
-
如果我们想让web-com继承div元素的特性 可以这么定义window.customElements.define('web-com',webCom,{extends:div}
自定义元素
- 一个 custom element 的类对象可以通过 ES 2015 标准里的类语法生成。所以,webCom可为
class webCom extends HTMLElement{ constructor(props) { // 必须首先调用 super 方法 super(props); // 以下写元素的功能代码 } }
- 上述代码片段中,类的构造函数
constructor
总是先调用super()
来建立正确的原型链继承关系。在构造函数中,我们会定义元素实例所拥有的全部功能。作为示例,我们首先 会将shadow root附加到custom element上,然后通过一系列DOM操作创建custom element的内部阴影DOM结构,再将其附加到 shadow root上,最后再将一些CSS附加到shadow root的style节点上
template 标签
- 通过template 标签给自定义元素定义结构样式 并且给模板指定id
<template id="webComTemplate"> <style> :host { display: flex; align-items: center; 600px; height: 500px; background-color: #d4d4d4; border: 1px solid #d5d5d5; box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.1); border-radius: 3px; overflow: hidden; padding: 10px; box-sizing: border-box; font-family: 'Poppins', sans-serif; } .container { box-sizing: border-box; padding: 20px; height: 500px; } .up { font-size: 20px; font-weight: bolder; } .down { margin: 10px 0; color: red; } img { 400px; height: 400px; } </style> <div class="container"> <div class="up"> </div> <div class="down"></div> <img class="img"> </div> </template>
style样式写在模板内部局部生效也可以外部引入样式
为自定义元素添加内容
-
class webCom extends HTMLElement { constructor(props) { super(props); // 指定模式 外部是否能够访问内部dom mode两种取值 closed禁止访问 open允许访问 var shadow = this.attachShadow({ mode: 'closed' }) // 获取template的模板 var tem = document.getElementById('webComTemplate') // 声明一个变量 保存模板的内容 var content = tem.content.cloneNode(true) // 给相应的元素设置属性 让元素的文本内容显示属性值 content.querySelector('.container>.up').innerText = this.getAttribute('title'); // 给相应的元素设置属性 让元素的文本内容显示属性值 content.querySelector('.container>.down').innerText = this.getAttribute('content'); // 给相应的元素设置属性 让img的的src属性等于设置的属性值 content.querySelector('img').setAttribute('src', this.getAttribute('img')); // 把模板的内容放入shadow shadow.appendChild(content); // 通过shadow Api获取元素 this.img = shadow.querySelector('img'); // 给元素监听相应事件 this.img.addEventListener('click', () => { }); } } window.customElements.define('web-com', webCom)
调用window.customElements.define('web-com',webCom)方法 生成自定义元素web-com
页面中使用web-com标签及显示效果
- 页面中使用
<web-com title="跟着大胖学前端" content="算了还是跟着大胖吃美食吧" img="./food.jpg" ></web-com>
- 页面显示效果
用户交互
- 如果需要交互 在类的内部 通过shadow api获取元素 监听事件
this.img = shadow.querySelector('img'); this.img.addEventListener('click',()=>{ });
生命周期回调函数在自定义的element的构造函数中,可以指定多个不同的回调函数,它们将会在元素的不同生命时期被调用
- connectedCallback:当 custom element首次被插入文档DOM时,被调用。
- disconnectedCallback:当 custom element从文档DOM中删除时,被调用。
- adoptedCallback:当 custom element被移动到新的文档时,被调用。
- attributeChangedCallback: 当 custom element增加、删除、修改自身属性时,被调用。