让前端飞

Web Components使用(二)

2020-10-22  本文已影响0人  张中华

在上一章节中主要介绍了Custom elements(自定义元素),Shadow DOM(影子DOM)的使用,我们发现其实只使用上述的两种方式,已经可以构建我们平时需要的组件,那么为什么还需要HTML templates(HTML模板)技术呢?
不知道大家还记不记得之前创建元素的方式:

        const input = document.createElement('input');
        input.setAttribute('type', 'text');
        input.setAttribute('class', 'input-vlaue');

创建一个input就需要写这些js代码,很明显,如果当html文档结构太深或者节点过多时,写出太多的创建html 节点的代码,还是很头疼的。一方面代码量过多且层级结构不清晰,另一方面时css也是用此方式创建,如何使用伪类呢? 多少是方便的。所以便有了HTML templates(HTML模板)技术。
我们先来看下它的定义:

HTML内容模板(<template>)元素是一种用于保存客户端内容机制,该内容在加载页面时不会呈现,但随后可以(原文为 may be)在运行时使用JavaScript实例化。") 和 <slot> 元素使您可以编写不在呈现页面中显示的标记模板。然后它们可以作为自定义元素结构的基础被多次重用。

其实就是它可以让你在编写组件时,可以预先定义好模板,然后再在模板上发展出自己的组件。
示例:
index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./main.js"></script>
</head>
<body>
    <template id="my-paragraph">
        <style>
          p {
            color: white;
            background-color: #909090;
            padding: 5px;
            border: 1px soli silver;
          }
        </style>
        <p><slot name="my-text">默认文本</slot></p>
      </template>
      
      <my-paragraph>
        <span slot="my-text">个性化文本</span>
      </my-paragraph>
    
      <my-paragraph>
        <ul slot="my-text">
          <li>列表条目1</li>
          <li>列表条目2</li>
        </ul>
      </my-paragraph>

</body>
</html>

main.js

customElements.define('my-paragraph',
  class extends HTMLElement {
    constructor() {
      super();

      const template = document.getElementById('my-paragraph');
      const templateContent = template.content;

      this.attachShadow({mode: 'open'}).appendChild(
        templateContent.cloneNode(true)
      );
    }
  }
);
运行结果

定义模板的的代码:

<template id="my-paragraph">
        <style>
          p {
            color: white;
            background-color: #909090;
            padding: 5px;
            border: 1px soli silver;
          }
        </style>
        <p><slot name="my-text">默认文本</slot></p>
</template>

由于这里的html import已经不被各大浏览器支持了,所以这里的定义模板的模块只能写到使用的html文本里面,或者使用js创建,写入到main.js里面。如下的例子,将template独立到js文件中。
示例:
index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./main.js"></script>
</head>
<body>
      <my-paragraph>
        <span slot="my-text">个性化文本</span>
      </my-paragraph>
    
      <my-paragraph>
        <ul slot="my-text">
          <li>列表条目1</li>
          <li>列表条目2</li>
        </ul>
      </my-paragraph>

</body>
</html>

main.js

const str = `
<style>
  p {
    color: white;
    background-color: #909090;
    padding: 5px;
    border: 1px soli silver;
  }
</style>
<p><slot name="my-text">默认文本</slot></p>

`;

customElements.define('my-paragraph',
  class extends HTMLElement {
    constructor() {
      super();

      const shadow = this.attachShadow({mode: 'open'});

      //const template = document.getElementById('my-paragraph');
      // const templateContent = template.content;
      const template = document.createElement('template');
      template.innerHTML = str;
      const templateContent = template.content;

      shadow.appendChild(
        templateContent.cloneNode(true)
      );
    }
  }
);

以上便是对Web Components的一个基本的认识和使用。由此可以看出Web Components在组件化开发方向的优势,可是在使用过程中也有一定劣势,以下便是目前自己不太喜欢的地方:

个人不太喜欢的地方
const str = `
<style>
  p {
    color: white;
    background-color: #909090;
    padding: 5px;
    border: 1px soli silver;
  }
</style>
<p class="test"><slot name="my-text">默认文本</slot></p>

`;

参考网址:
MSDN:https://developer.mozilla.org/zh-CN/docs/Web/Web_Components
W3C: https://www.w3.org/html/ig/zh/wiki/Web-Components#.E7.AE.80.E4.BB.8B
web componets 实例代码:https://github.com/mdn/web-components-examples
HTML5 Rocks: https://www.html5rocks.com/en/tutorials/webcomponents/customelements/#instantiating
阮一峰:https://javascript.ruanyifeng.com/htmlapi/webcomponents.html#toc12
知乎:https://zhuanlan.zhihu.com/p/64619005

上一篇 下一篇

猜你喜欢

热点阅读