Web Components
三个主要组成部分:
- Custom Elements(自定义元素)
- Shadow DOM(影子DOM)
- HTML Templates(HTML模板)
与Vue自定义组件的区别
Custom Elements
允许开发者创建新的 HTML 元素,并且可以定义它的行为和样式
创建自定义元素
class MyButton extends HTMLElement {
constructor() {
super();
const shadowRoot = this.attachShadow({ mode: 'open' });
shadowRoot.innerHTML = `
<style>
button {
background-color: #4CAF50;
border: none;
color: white;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px;
cursor: pointer;
padding: 10px 24px;
border-radius: 4px;
}
</style>
<button>Click Me!</button>
`;
}
}
customElements.define('my-button', MyButton);
生命周期回调方法
Custom Elements 也有一组生命周期回调方法,这些方法在元素的不同生命周期阶段被调用。这些生命周期方法允许你在元素的创建、插入文档、更新和删除等时刻执行操作。
以下是自定义元素的一些主要生命周期回调方法
constructor() : 构造函数,在创建元素实例时调用。适用于执行初始化操作,例如设置初始属性、添加事件监听器或创建 Shadow DOM。
connectedCallback() : 当自定义元素被插入到上下文时调用。适用于元素被插入到 DOM 时执行的操作,例如获取数据、渲染内容或启动定时器。
disconnectedCallback() : 当自定义元素从文档中移除时调用。适用于元素从 DOM 中移除时执行的操作,例如移除事件监听器或停止定时器。
attributeChangedCallback(attributeName, oldValue, newValue) : 当自定义元素的属性被添加、移除或更改时调用。要使用这个回调,你需要在类中定义一个静态的 observedAttributes 属性,列出你想要监听的属性。
constructor() {
super();
// 初始化操作,例如创建 Shadow DOM
const shadowRoot = this.attachShadow({ mode: 'open' });
shadowRoot.innerHTML = '<p>这是一个自定义元素</p>';
}
connectedCallback() {
// 元素被插入到 DOM 时执行的操作
console.log('Custom element connected to the DOM');
}
disconnectedCallback() {
// 元素从 DOM 中移除时执行的操作
console.log('Custom element disconnected from the DOM');
}
attributeChangedCallback(name, oldValue, newValue) {
// 监听的属性发生变化时执行的操作
console.log(`Attribute ${name} changed from ${oldValue} to ${newValue}`);
}
static get observedAttributes() {
// 返回一个数组,包含需要监听的属性
return ['my-attribute'];
}
}
customElements.define('my-custom-element', MyCustomElement);
<my-custom-element my-attribute="value"></my-custom-element>
在一个组件中,插槽将会照常使用 <slot/> 渲染。然而,当使用最终的元素时,它只接受原生插槽的语法:
- 不支持作用域插槽
- 当传递具名插槽时,应使用
slotattribute 而不是v-slot指令
Shadow DOM
允许将一个独立的DOM树附加到某个元素上,这个DOM树与主文档DOM分开呈现,从而实现了元素内部结构和样式的封装。
创建流程
Shadow DOM 是一种在一个 DOM 节点内部创建独立的、封装的 DOM 子树。 这使得一个元素定义独立的 UI 结构和样式,而不会影响到页面上的其他部分。 隔离性:内部的 CSS 样式不会泄漏到外部 DOM
隔离性
shadow dom是游离在 DOM 树之外的节点树,但是它是基于普通 DOM 元素(非 document)创建的,并且创建后的 Shadow-dom 节点可以从界面上直观的看到。最重要的一点是Shadow-dom 具有良好的密封性。
自定义元素外的 wx_name并没有应用颜色样式效果,因为整个 shadowRoot 对象和文档对象完全隔离的
mode
mode: 'open':允许外部通过宿主元素的shadowRoot属性,通过 Element.shadowRoot 属性访问Shadow DOM。
mode: 'closed':禁止外部访问Shadow DOM,增强了封装性。
当一个元素使用 Shadow DOM 创建时,它会包含一个 Shadow Root,这是一个独立的 DOM 子树,与文档中的其他部分相互隔离,可以在其中定义和控制样式和行为。
HTML Templates(HTML模板)
HTML Templates 是一种用于定义可复用的 HTML 结构的技术。模板中的内容不会立即渲染到页面上,而是可以在需要时通过 JavaScript 动态插入到文档中
基本用法
使用 <template> 标签定义模板。
<div>
<h1>Hello, Template!</h1>
<p>This is a reusable template.</p>
</div>
</template>
通过 JavaScript 将模板内容插入到文档中。
const clone = template.content.cloneNode(true);
document.body.appendChild(clone);
WebComponents例子
举个例子:创建一个自定义元素,然后将其挂载到真实 DOM 或者 shadow DOM 上
extends
options:【可选】控制元素如何定义,只支持一个选项 extends,用于指明定义的元素继承自何种类型元素。
(例如:{ extends: 'p’ })
这里 extends 指明的元素是 HTMLParagraphElement,在调用 define 方法的时候 extends 必须指明为 p,同时组件也只能用在 p 元素上,方式上有别于一般的自定义元素