Wscats/node-tutorial

无依赖自定义组件的实践

Wscats opened this issue · 0 comments

组件

无依赖自定义组件的实践需要依赖三个技术(浏览器原生就支持组件化)

  • Custom elements(自定义元素)customElements.define('my-header', Xheader)
  • Shadow DOM(影子DOM)attachShadow
  • HTML templates(HTML模板)<template>和 <slot>
// HTML模板技术包含两个标签:<template>和 <slot>
// 当需要在页面上重复使用同一个 DOM结构时,可以用 template 标签来包裹它们,然后进行复用
// slot标签让模板更加灵活,使得用户可以自定义模板中的某些内容
const str =
    `
    <style>
        header {
            height: 50px;
            line-height: 50px;
            width: 100%;
            text-align: center;
            color: white;
            background-color: red;
        }
    </style>
    <header><slot name="my-title">头部</slot></header>
    `
class Xheader extends HTMLElement {
    constructor() {
        super();
        const template = document.createElement('template');
        template.innerHTML = str;
        const templateContent = template.content;
        // 创建一颗可见的DOM树,这棵树会附着到某个DOM元素上
        // 这棵树的根节点称之为shadow root,只有通过shadow root 才可以访问内部的shadow dom,并且外部的css样式也不会影响到shadow dom上
        // 相当于创建了一个独立的作用域
        this.attachShadow({
            mode: 'open'// 'open' 表示该shadow dom可以通过js 的函数进行访问
        }).appendChild(
            templateContent.cloneNode(true)// 操作shadow dom
        );
    }
}
// 允许自定义元素及其行为,然后可以在您的用户界面中按照需要使用它们
customElements.define('my-header', Xheader);

事件绑定

经过测试,发现需要在appendChild()之后,才能绑定事件

attachShadow.appendChild(
    templateContent.cloneNode(true) // 操作shadow dom
);
// 编译模板,要在appendChild之后
attachShadow.querySelector(xxx);
let nodes = attachShadow.childNodes;