我们好,这里是我们的林语冰。坚持阅览,自律打卡,每天一次,前进一点

免责声明

本文属于是语冰的直男翻译了属于是,略有删改,仅供粉丝参考。英文原味版请传送 Getting into web components – an intro

本期同享的是 —— 今年关于 WC(Web Components,Web 组件)而言兹事体大,本人对此感到鸡冻。说实话,不久前本人对 WC 简直一窍不通,由于私以为 WC 只是网络上不值一提的蜉蝣之物。但 WC 正在引起更多论题。所以我想更多地了解 WC。

Web Components,发动!

WC 是什么鬼物?

WC 就像网站的构建块,甚至可能是构建块组。

咱们能够自界说元素,比方 <my-button><for-love>,而不是循规蹈矩地运用 <div><button> 等规范标签。自界说元素代表咱们能够在网站或网络 App 中运用和重用的独特组件。自界说元素内部始终需要有一个连字符,用来区分其与规范 HTML 元素,并遵循 WC 规范设置的命名约好。

连字符背面的主要原因是为了避免抵触,削减与规范 HTML 元素发生命名抵触的时机。由于规范 HTML 元素不包括连字符(当然,现在永久不会包括连字符)。

Shadow DOM

Shadow DOM 就像一个 Web 元素的“密室”。假设咱们有一个作业区,咱们正在其中构建网站的不同部分。某些部分需要在不影响其余部分的情况下完成作业。Shadow DOM 供给了一个封装的空间来完成这一点。这个“密室”内的元素能够有自己的款式、脚本和结构,而不会干扰主页或其他元素的款式和脚本。咱们所指的其他元素便是咱们所说的“Light DOM”。

<div>
  <p>This is content outside the Shadow DOM, thus "Light DOM".</p>
  <my-element></my-element>
</div>
<script>
  // 创立一个新的自界说元素
  class MyElement extends HTMLElement {
    constructor() {
      super()
      // 为自界说元素创立 Shadow DOM
      const shadow = this.attachShadow({ mode: 'open' })
      // 在 Shadow DOM 里创立 p 标签
      const paragraph = document.createElement('p')
      paragraph.textContent = 'Shadow DOM 里的内容'
      // 将 p 标签添加到 Shadow DOM
      shadow.appendChild(paragraph)
    }
  }
  // 界说自界说元素
  customElements.define('my-element', MyElement)
</script>

Shadow DOM 有某些详细的特征:

封装:在 Shadow DOM 里,咱们的款式和脚本不会受到外界的影响。此行为有助于防止款式意外与网页上其他元素混杂。除了自界说特点之外,外部 CSS 不会对其发生任何影响。

组合:Shadow DOM 引入了插槽,即迷你占位符,咱们能够在其中刺进自界说内容。这意味着,咱们能够自界说元素的内部,而不会破坏原始设计。

举个栗子,咱们将在 WC 内刺进 <h2><p>。它仅有要做的便是,在它们之间放置一个 <hr>

<my-card>
  <!-- Content placed inside the slots -->
  <h2 slot="title">Card Title</h2>
  <p slot="content">This is the content of the card.</p>
</my-card>
<script>
  class MyCard extends HTMLElement {
    constructor() {
      super()
      // 为自界说元素创立 Shadow DOM
      const shadow = this.attachShadow({ mode: 'open' })
      // 为卡片内容创立容器
      const cardContainer = document.createElement('div')
      // 为标题创立插槽
      cardContainer.innerHTML = `
          <slot name="title"></slot>
          <hr>
          <slot name="content"></slot>
        `
      // 将卡片容器添加到 Shadow DOM
      shadow.appendChild(cardContainer)
    }
  }
  customElements.define('my-card', MyCard)
</script>

现在幻想一下 JS 失利了,页面仍然会显现 WC 内部供给的插槽内容,由于这只是一些轻量级 DOM,仅有短少的是 <hr>。即便咱们有必要支持不支持此功能的浏览器,它仍然可能是一个渐进增强。

可访性:可拜访性是一种同享言语。Shadow DOM 里的元素能够了解并运用与外部元素相同的辅佐言语。更重要的是,它确实能够辅佐咱们处理某些更难拜访的用例,比方选项卡。

关注点别离:Shadow DOM 可让咱们将结构、款式和行为规整地排列在各自的分区中。幻想一下,拥有一个用于所有这些重复使命的 WC 库:可拜访的选项卡、图像缩放和可动画的下拉菜单。咱们仍然能够运用自界说特点来设置款式,由于这些特点会渗透到 WC 中。

::part 伪元素:它允许咱们从 Shadow DOM 外部设置 WC 的特定命名部分的款式。

举个栗子:

<my-element>
  <h2 slot="header">头部内容</h2>
  <p slot="content">主内容</p>
</my-element>

这便是咱们的 WC 的姿态(粉丝请注意 innerHTML 的特点):

class MyElement extends HTMLElement {
  constructor() {
    super()
    const shadow = this.attachShadow({ mode: 'open' })
    shadow.innerHTML = `
	    <style>
            div {
            border: 3px solid blue;
            }
        </style>
        <div part="header"><slot name="header"></slot></div>
        <hr/>
        <div part="content"><slot name="content"></slot></div>
    `
  }
}
customElements.define('my-element', MyElement)

现在解说这一点的最好办法是用边框将其可视化。默许情况下,影子 DOM 内的 <div> 元素具有蓝色边框。咱们想要为包裹标题槽的 <div> 供给绿色边框,咱们能够拜访它:

/* h2 默许款式 */
h2 {
  margin-block: 30px;
  color: red;
  border: 3px solid red;
}
/* 头部的绿色边框 */
my-element::part(header) {
  border: 3px solid green;
}

WC 的开发体验

像这样编写 WC 并不是一种很好的开发人员体验……至少在我看来。关于根本示例而言,它好像作业得很好,但我只是喜欢编辑器中的一些结构和色彩,而不是只是将每个输出放入字符串中。

咱们能够运用 Lit 库来辅佐创立 WC。Lit 库旨在使 WC 的运用更轻松高效。它供给了若干长处,只需以正常方式编写它们就能够减轻一些负担。

Lit 供给了一种更具声明性的语法来界说组件。运用此办法能够使咱们的代码更易于了解和管理,而不是直接处理 WC API 时所需的更复杂的款式。它还具有这个简练的模板体系,结合了 HTML 和 JS 模板字符串,使处理动态内容愈加方便。这不仅有助于咱们的编辑器中呈现某些美丽的色彩,还有助于其更新策略,即只更新 DOM 中已更改的部分。与手动更新比较,这能够提高性能。

综合考虑所有这些因素,如果您认真对待 WC,我想说值得一看,由于这个库的巨细只有 6kb 左右。

本期论题是 —— 您开始运用 Web Components 了吗,有遭遇什么痛点吗?

欢迎在本文下方群聊自由言论,文明同享。谢谢我们的点赞,掰掰~

前端 9 点半》每日更新,坚持阅览,自律打卡,每天一次,前进一点

Web Components,发动!