Web Components 学习笔记二:使用 Custom Elements 创建可复用的自定义组件

577 阅读3分钟

公众号:妙蛙种子前端

原文地址:Web Components 笔记二:使用 Custom Elements 创建可复用的自定义组件 | 妙蛙种子 - 记录WEB前端技术学习成长过程的博客

WX20220325-010758@2x.png

上一个笔记记录了什么是Web Component,它出现的背景是什么,解决了什么问题。详细查看:

Web Components笔记一: Web Components是什么?解决了什么问题? | 妙蛙种子 - 记录WEB前端技术学习成长过程的博客

本次笔记我们尝试使用 Custom Elements 的来定义一个可以在页面上随意复用的自定义组件。组件为一个猫咪眼珠跟随小球运动的css动效,效果如:

image.png

DEMO在线地址: Custom Element - Web Component 

创建组件模版

我们编写组件的目的就是为了dom、样式、事件的复用,因此我们需要使用一个组件模版来承载这些复用的东西。我们可以使用 HTML 的内容模版 <tenplate> 标签来保存组件的内容。

HTML 内容模板(<template>)元素是一种用于保存客户端内容机制,该内容在加载页面时不会呈现,但随后可以在运行时使用 JavaScript 实例化。

我们可以使用如下代码声明一个 template 模版块:

<template id="component1">
    <div>组件1</div>
</template>

我们虽然是在html中声明模版内容,但这只是为了将内容视为一个可存储的内容片段。虽然浏览器在加载页面时确实会处理  <template> 元素的内容,但这样做只是为了确保这些内容有效,元素内容并不会被渲染到页面上。

我们使用 template 标签定义一下猫咪动效所需的css和html结构,如下:

<template id="cat-template">
  <style>
    .wrapper {
      display: flex;
      justify-content: center;
      align-items: center;
      height: 200px;
    }
 
    .cat {
      position: absolute;
      width: 200px;
      height: 100px;
      /*   margin: 20px auto; */
      overflow: hidden;
      background-color: #fff;
    }
    // ...省略大段样式定义,详细查看末尾完整代码
  </style>
 
  <div class="wrapper">
    <div class="cat">
      <img src="./images/cc.png" />
      <div class="eyelids"></div>
      <div class="eye left">
        <div class="eyeWatch">
          <div class="glare"></div>
        </div>
      </div>
      <div class="eye right">
        <div class="eyeWatch">
          <div class="glare"></div>
        </div>
      </div>
      <div class="nose"></div>
      <div class="claws c1"></div>
      <div class="claws c2"></div>
      <div class="claws c3"></div>
      <div class="claws c4"></div>
      <div class="claws c5"></div>
      <div class="claws c6"></div>
    </div>
    <div class="ballContainer">
      <div class="ballShadow">
        <div class="ball"></div>
      </div>
    </div>
    <div class="ears">
      <div class="ear eLeft"></div>
      <div class="ear eRight"></div>
    </div>
  </div>
</template>

我们给 <template id="cat-template"> 加上了id,方便后续使用 js 对组件的模版进行引用。

定义自定义元素

使用过Vue自定义组件的小伙伴都知道,我们定义组件后,可以在页面中直接使用自定义组件的标签进行引用。Web Component也是一样,我们可以定义一个自定义组件的标签,在页面中直接引用标签渲染组件。

上一节有提到,定义自定义元素,使用的是Custom Element特性,我们可以通过继承HTMLElement来自定义一个 CatElement 元素类:

class CatElement extends HTMLElement {
  constructor() {
    // 必须首先调用 super方法
    super();
 
    // 元素的功能代码写在这里
    ...
  }
}

然后使用 Shadow DOM 特性,为 CatElement 定义一个局部作用域的私有空间,然后获取到template的内容添加到 Shadow 中。最后使用 customElements.define 将 CatElement 类声明成一个自定义的标签,并且给 CatElement 元素设置了标签别名为 cat-demo 。

<script>
  class CatElement extends HTMLElement {
    constructor() {
      // 必须首先调用 super方法
      super();
        
      const template = document.getElementById("cat-template");
      const templateContent = template.content;
      console.log(templateContent, "templateContent");
      const shadowRoot = this.attachShadow({ mode: "open" });
      shadowRoot.appendChild(templateContent.cloneNode(true));
    }
  }
 
  customElements.define("cat-demo", CatElement);
</script>

到这一步,自定义组件基本已经完成。我们通过template定义了组件模版,通过 Custom Element 和 Shadow DOM 特性定义组件元素对象信息。

最终,我们就可以直接在html中使用 <cat-demo></cat-demo> 标签来引用我们的组件。使用这种方法创建的组件,组件间的状态是完全隔离的,外部样式不会影响到内部样式。

DEMO完整示例代码

github.com/vipchens/le…

Web Components学习笔记系列:

Web Components 学习笔记一: Web Components是什么?解决了什么问题?

Web Components 学习笔记二:使用 Custom Elements 创建可复用的自定义组件

交个朋友吧

交个朋友,关注 「妙蛙种子前端」 公众号吧!

妙蛙种子前端是一个记录/分享WEB前端技术相关的前端公众号,始于前端又不止于前端,包括但不限于前沿互联网只是、学习笔记、认知提升等内容。