Skip to content

Web Components - MDN

框架组件与原生组件Web Components

不使用前端框架,我们需要面临缺少

  • 良好的生态
  • 数据驱动视图
  • 模块化
  • 组件化
  • 等等的问题

但是官方现在其实已经支持原生的模块化了 ES Module 而组件化,官方也推出了 Web Components

我们再来看看框架里的组件化 如 vue 支持我们开发过程编写 <my-button> 的标签,对应这一个UI组件 但是在运行时这个 <my-button> 是打包后被编译成普通的 <div> 标签来渲染的

而原生的 Web Components 则是浏览器在运行时真正以自定义标签的 <my-button> 来进行渲染的


思考1🤔:

框架中的组件被编译成div让浏览器运行,我们可以类比其他的场景

如: css预处理器 (scssless),里的变量的概念,是通过编译时把真实变量值替换到变量引用的地方,到浏览器运行时是真正的值而不是变量 而css原生后来推出的变量才是浏览器运行时真正的变量

css预处理器变量原生css变量的区别:

  • scss等预处理器的变量通过编译实现的原理,导致我们并不能在运行时浏览器js中操作 scss 的变量
  • 编译后的scss变量就不再是变量了
  • 而原生css变量,可以被浏览器运行时的js操作,并且引用的地方就能更新变量值

思考2🤔: 原生吸收框架的设计是很常见的情况 如 jQuery 的核心功能之一快捷选择dom的 $(),被官方的querySelector()querySelectorAll()所替代

vuereact ,目前官方文档中都有使用 Web Components 的介绍 毕竟框架提供的数据驱动视图组件通信复杂逻辑复用,用来开发组件才是更方便的,所以只用 Web Components 来一把梭哈,还是不方便 相反,配合着框架使用达到互补的效果才是目前最香的


web Components优点

而原生组件化最大的好处在于它是脱离框架的,即原生组件即可在 vue 中使用也可以在 react 中使用

web components 完整优点 -阿里巴巴大淘宝技术

从作用上看,是组件

从特性上看,像iframe

Web Components 示例

html
<html>
  <head>
    <meta charset="utf-8">
    <title>demo</title>
    <script src="main.js" defer></script>
  </head>
  <body>
    <open-shadow text="I have an open shadow root"></open-shadow>
  </body>
</html>
js
customElements.define('open-shadow',
  class extends HTMLElement {
    constructor() {
      super();

      const pElem = document.createElement('p');
      pElem.textContent = this.getAttribute('text');

      const shadowRoot = this.attachShadow({mode: 'open'});
      shadowRoot.appendChild(pElem);
    }
  }
);

除了用js来创建 Web Components,还可以用html来创建,这样的写法会跟 vueSFC 文件非常相像 如👇

html
<html>
  <head>
    <meta charset="utf-8">
    <title>demo</title>
    <link rel="import" href="test.html">
  </head>
  <body>
    <my-p>123</my-p>
  </body>
</html>
html
<template>
  <p>
    <slot></slot>
  </p>
</template>

<script>
const dom = document.currentScript.ownerDocument.querySelector('template').content

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

    this.attachShadow({ mode:'open' }).appendChild(dom)
  }
})
</script>

<style>
p{
  color: red;
}
</style>

👆 可以看到这个html文件和vue2的写法很像,但是style标签没有生效(FIXME: ),可能废弃了?

这里的 Web Components 并不是一种单一的技术,而是4种技术

  • HTML Imports (谷歌79以上废弃)
  • HTML templates
  • Custom Elements
  • Shadow DOM

HTML Imports(谷歌79以上废弃)

<link rel="import" href="xxx.html"> 其实是一种html的模块化