Web Components — Web 组件

前言

在重学 JavaScript 过程中,了解到了 Web 组件,而其中的一些知识点总感觉和 vuejs 中的某些概念很相似,比如 Web 组件中涉及的内容:

  • HTML 模板,即 template 标签
  • 自定义元素
  • 影子 DOM 和 slot 标签
  • 影子 DOM 实现样式隔离

那么下面就一起看看 Web 组件的这些内容和 vue 中的某些概念相似在哪吧!

Web Components

Web 组件到底是什么?

Web 组件其实就是一套用于增强 DOM 行为的工具,其内容包括 影子 DOM自定义元素HTML 模板 等.

目前 Web Components 没有得到广泛应用,主要是因为存在以下问题:

  • 没有统一的 “Web Components” 规范
  • Web 组件存在向后不兼容的版本问题
  • 浏览器实现极其不一致

由于存在这些问题,因此使用 Web 组件通常需要引入一个 Web 组件库,用于模拟浏览器中缺失的 Web 组件. 比如 PolymerLitElement,新项目更推荐使用 LitElement.

HTML 模板 —— template 标签

我们可以先思考下面的问题,并尝试给出一些解决方法。

问题:如何把对应的三个背景颜色分别为红绿蓝的 p 标签,3s 后动态渲染在指定的位置中,如 <div id="root"></div>
方案一: 使用 innerHtml

    let divRoot =  document.querySelector("#root");
    setTimeout(()=>{
   
   
        divRoot.innerHTML = `
         <p class="red">Make me red!</p> 
         <p class="blue">Make me blue!</p> 
         <p class="green">Make me green!</p> 
       `
    },3000);

方案二: 使用 createElement + createDocumentFragment + appendChild

    let divRoot =  document.querySelector("#root");
    let colors = ['red','blue','green'];
    
    let fragment =  document.createDocumentFragment();
    for (const color of colors) {
   
   
      const p = document.createElement('p');
      p.className = color;
      p.innerText = `Make me ${
     
     color}!`
      fragment.appendChild(p);
    }
    setTimeout(()=>{
   
   
        divRoot.appendChild(fragment);
     },3000);

通过 方案一 和 方案二 都能实现对应的效果,但是对于书写 HTML 结构来讲都是不友好的,首先就是它们都无法做到像直接书写 HTML 时的友好提示,其次就是它们都只适用结构非常简单的内容,一旦结构内容有多层嵌套时,单纯设计 html 结构就变得很复杂。

使用 <template> 标签

PS: <template> 标签是 HTML 中存在的,并不是 vue 中特有的,不要混淆.

在有 Web 组件之前,一直缺少基于 HTML 解析构建 DOM 子树,然后在需要时再把这个子树渲染出来的机制.

Web 组件中,可以通过使用 <template> 标签提前在页面中写出特殊标记,让浏览器自动将其解析为 DOM 子树,但跳过渲染. 如下:

<body>
  <template id="tpl">
    <p>I'm inside a custom element template!</p>
  </template>
</body>

在浏览器中通过开发者工具检查网页内容时,可以看到 <template> 标签中渲染的节点内容 是基于 DocumentFragment,而 DocumentFragment 也是批量向 HTML 中添加元素的高效工具,此时的 DocumentFragment 就像一个对应子树的最小化 document 对象,也就是说,如果需要操作 <template> 标签中节点,必须要先获取对应 DocumentFragment 的引用,即 document.querySelector('#tpl').content.

下面是通过 <template> 标签实现上面问题的解决方案:

<body>

  <div id="root"></div>

  <template id="tpl">
    <p class="red">Make me red!</p>
    <p class="blue">Make me blue!</p>
    <p
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值