Web Components:基础知识

前言

组件是前端的发展方向,现在流行的 React 和 Vue 都是组件框架。
谷歌公司由于掌握了 Chrome 浏览器,一直在推动浏览器的原生组件,即 Web Components API。相比第三方框架,原生组件简单直接,符合直觉,不用加载任何外部模块,代码量小。目前,它还在不断发展,但已经可用于生产环境。

怎么说呢,无意中就发现了这个东西,感觉很有意思,打算学习研究一下。

参考:

自定义元素

自定义元素比如:<user-card></user-card>,这种自定义的 HTML 标签,称为自定义元素(custom element)。根据规范,自定义元素的名称必须包含连词线,用与区别原生的 HTML 元素。

组件示例

组件user-card.js

const template = document.createElement('template');

template.innerHTML = `
  <style>
    h2 {
      border:1px solid red;
    }
  </style>

  <h2>
    <span>Hello World</span>
  </h2>
`;
class UserCard extends HTMLElement {
    
    
  constructor() {
    
    
    super()
    let shadow = this.attachShadow({
    
     mode: 'closed' });
    shadow.appendChild(template.content.cloneNode(true));
  }
}

window.customElements.define('user-card', UserCard);

使用test.vue

<template>
    <div>
        <user-card id="test"></user-card>
    </div>
</template>

<script setup lang="ts">
import './components/user-card.js';
</script>

<style scoped lang="scss">
</style>

在这里插入图片描述

customElements.define()

自定义元素需要使用 JavaScript 定义一个类,所有<user-card>都会是这个类的实例。
浏览器原生的customElements.define()方法,告诉浏览器<user-card>元素与这个类关联。

语法

customElements.define(name, constructor, options);
name:自定义元素名
constructor:自定义元素构造器
options:控制元素如何定义. 目前有一个选项支持,extends. 指定继承的已创建的元素. 被用于创建自定义元素.

template和slot

使用 <template><slot> 元素创建一个可以用来灵活填充 Web组件的 shadow DOM 的模板。
这里不介绍,根vue中的模板和插槽没什么区别,具体内容见:使用 templates and slots

attachShadow

语法

var shadowroot = element.attachShadow(shadowRootInit);

用来指定模式,官网的说明是:attachShadow
在这里插入图片描述

class UserCard extends HTMLElement {
    
    
  constructor() {
    
    
    super()
    let shadow = this.attachShadow({
    
     mode: 'open' });
    shadow.appendChild(template.content.cloneNode(true));
  }

  connectedCallback() {
    
    
    console.log("添加到页面")
    this.updateStyle(this);
  }

  updateStyle(elem) {
    
    
    //获取根节点
    let shadowRoot = elem.shadowRoot
    // open时可以获取到,closed时为null
    console.log("根节点:", shadowRoot)
  }
}

shadow DOM

Web components 的一个重要属性是封装——可以将标记结构、样式和行为隐藏起来,并与页面上的其他代码相隔离,保证不同的部分不会混在一起,可使代码更加干净、整洁。其中,Shadow DOM 接口是关键所在,它可以将一个隐藏的、独立的 DOM 附加到一个元素上。本篇文章将会介绍 Shadow DOM 的基础使用。

Shadow DOM 允许将隐藏的 DOM 树附加到常规的 DOM 树中——它以 shadow root 节点为起始根节点,在这个根节点的下方,可以是任意元素,和普通的 DOM 元素一样。

有一些 Shadow DOM 特有的术语需要我们了解:

  • Shadow host:一个常规 DOM节点,Shadow DOM 会被附加到这个节点上。
  • Shadow tree:Shadow DOM内部的DOM树。
  • Shadow boundary:Shadow DOM结束的地方,也是常规 DOM开始的地方。
  • Shadow root: Shadow tree的根节点。

设置样式:

  • 方式一:最开始的那个例子的格式
  • 方式二:
var style = document.createElement('style');
style.textContent = `
  .wrapper {
	  position: relative;
  }
  ....
`
shadow.appendChild(style);
  • 方式三:加载外部样式
const linkElem = document.createElement('link');
linkElem.setAttribute('rel', 'stylesheet');
linkElem.setAttribute('href', 'style.css');

// 将所创建的元素添加到 Shadow DOM 上

shadow.appendChild(linkElem);

推荐使用前两种方式, 因为<link> 元素不会打断 shadow root 的绘制, 因此在加载样式表时可能会出现未添加样式内容,导致闪烁。

生命周期

定义在自定义元素的类定义中的特殊回调函数,影响其行为:

  • connectedCallback: 当自定义元素第一次被连接到文档DOM时被调用。
  • disconnectedCallback: 当自定义元素与文档DOM断开连接时被调用。
  • adoptedCallback: 当自定义元素被移动到新文档时被调用。
  • attributeChangedCallback: 当自定义元素的一个属性被增加、移除或更改时被调用。

猜你喜欢

转载自blog.csdn.net/weixin_41897680/article/details/125036346