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

824 阅读4分钟

公众号:妙蛙种子前端

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

Web Components是HTML5提供的一种原生组件封装集成的方式,我们可以通过这种技术封装一些类似Vue自定义组件的元素,在html中直接使用。

提到Web Components我们优先会提到组件化,什么是组件化?指的是将相似的业务抽离成固定的交互形式,然后通过html、JavaScript、css去实现这个交互,并且将这个交互的html、JavaScript、css合并在一个独立、封闭的空间内,对外暴露功能接口。用面向对象的思维来看就是:高内聚、低耦合。

前端组件化的阻碍

在jQuery的时代,我们都会遇到这种场景:引入一个幻灯片的插件,js、css都正常引入了,但样式却和官方demo不一致。细查后发现其实是我们全局的css影响了插件的样式。 当然第三方插件也有可能影响到我们的主页面,举个例子:

组件一:

<div>组件一</div>
 
<style>
    div {
    	color: red;
    }
</style>

组件二:

<div>组件二</div>
 
<style>
    div {
    	color: blue;
    }
</style>

以上两个组件分别定义了自己的div标签,并且对自己的div设置了独立的样式。如果将两个组件放在同一个页面的时,就会发现其中一个组件的样式影响到了另一个组件。同时,如果我们在组件内通过JavaScript获取所有的div进行dom操作,也会影响到其他组件的div。

为什么会这样?因为css是影响全局的,并且在页面的任何js中,我们都能通过api操作页面的dom。

Vue是如何解这类问题的?

Vue在定义组件时,可以给组件的 <style> 标签增加了 scoped 属性,来表示标签中的内容为组件局部的样式。如:

<template>
    <div>组件一</div>
</template>
 
<style scoped>
    div {
        color: red;
    }
</style>

在编译时使用 vue-loader 编译这个组件时,会给这个组件生成一个独一无二的ID,作为这个组件的tag。

  • 在编译 <template> 时会为每个标签打上 data-v-{组件ID} 的属性,如:
<div data-v-73637230>组件一</div>
  • 在编译样式时也会将带有 scoped 属性的 css 也通通打上data-v-{组件ID} 的属性选择器,如:
div[data-v-73637230] {
    color: red;
}

Web Components如何解决组件作用域问题的?

基于以上的问题,现代浏览器提供了两个特性让我们能自由的创建一些可复用的组件,并且组件的状态与外部是完全隔离开的。

Custom Element 特性

创建一个继承 HTMLElement 的自定义dom元素,可以自定义dom元素的各种生命周期,实现dom的自定义功能,如:

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

Shadow DOM 特性

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

image.png

我们可以使用js的api来操作 Shadow DOM ,就和操作常规 DOM 一样。例如添加子节点、设置属性,以及为节点添加自己的样式(例如通过 element.style 属性),或者为整个 Shadow DOM 添加样式(例如在 <style> 元素内添加样式)。不同的是,Shadow DOM 内部的元素始终不会影响到它外部的元素(除了 :focus-within),这为封装提供了便利。

当然 Shadow DOM 也不算是很新的东西,很早前就已经有实际的用途,例如 <video> 标签实际上就是运行在  Shadow DOM 中,包含了一系列的按钮和其他控制器。Shadow DOM 标准允许你为你自己的元素(custom element)维护一组 Shadow DOM。

Web Components学习笔记系列:

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

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

交个朋友, 关注 “妙蛙种子前端” 公众号吧

WX20220326-215228@2x-小.png