kd-cloud-web / Blog

一群人, 关于前端, 做一些有趣的事儿
13 stars 1 forks source link

关于Web Components #44

Open doreenChenD opened 4 years ago

doreenChenD commented 4 years ago
  1. 从前端组件化到Web Components
  2. 主要的API与兼容性
  3. webcomponentsjs,AMP,Polymer
  4. react、vue、angular和web components

从前端组件化到Web Components

在 Github 等社区和绝大多数互联网公司,从未停止过对前端组件化的尝试。 这些尝试产生了大量的各式各样的组件化技术,它们在解决的问题粒度、 提倡的架构设计、编译和处理的时机等方面各有不同:

  1. 从预编译时进行处理的 ES6 模块,到运行时异步加载的 AMD 模块;
  2. 从简单的 RoR (Ruby on Rails)简单的服务器端 MVC 设计,到 AngularJS/Vue.js 的前端 MVVM;
  3. 从 LESS 等单个语言的预编译工具,到 webpack 这样的全站打包工具。

为什么前端组件化?

  1. 项目复杂度增加, 一个页面一个文件需要处理的内容过多.
  2. 重复性劳动多, 效率低
  3. 质量差, 不可控

前端组件化困难的一些原因

  1. 缺乏 JavaScript 模块化标准
  2. CSS 的全局作用域
  3. 全局 DOM 和 Window 的设计

现有的组件化的一些方案?

  1. jQuery 插件机制:
    $(".select").pluginName(config)
  2. 对象模式,各类库, 如swiper.js:
    <!-- Slider main container -->
    <div class="swiper-container">
    <!-- Additional required wrapper -->
    <div class="swiper-wrapper">
        <!-- Slides -->
        <div class="swiper-slide">Slide 1</div>
        <div class="swiper-slide">Slide 2</div>
        <div class="swiper-slide">Slide 3</div>
        ...
    </div>
    </div>
    <script src="path/to/swiper.min.js"></script>
    <script>
    var mySwiper = new Swiper ('.swiper-container', {
    direction: 'vertical',
    loop: true,
    })
    </script>
    • 现代组件结构 前端框架 Vue React 已经是组件化的集大成者。
  3. 我们期望的组件 (1)可拓展性:既然组件是针对某一特定功能或需求开发的,那它就必须易于开发和拓展; (2)封装性:组件作为一个独立整体供使用,应该是高內聚低耦合的。遵守开放封闭原则,只供使用,而不对使用环境产生副作用; (3)易用性:组件的目的是产生可重用的独立部件,那就必须提供一种简单快捷的方式供使用。
  4. 组件的结构 (1)隔离的UI,包括内容,样式 (2)隔离的功能属性attribute,property,status(内部状态), method (3)各自的生命周期 生命周期通常有, 创建, 挂载, 销毁前等, vue 和 react 设计了更细粒度的生命周期. 为什么要有生命周期, 因为我们在设计好一个组件已经组件的功能时, 我们需要在一些特定的时候执行一些代码, 比如初始化动作, 获取数据动作等. 我们把做这些动作的时机整理后发现, 我们往往需要在创建的时候需要做一些动作, 在构建好组件的 dom 挂载到页面的时候需要做一些动作, 在销毁前需要做一些动作比如内存释放等. 因此这些时机也在现代框架中得到了标准的支持.

什么是Web Components?

Web Components 是 WHATWG 和 W3C 正在尝试的 Web 组件化方案,为组件化的 Web 前端开发提供浏览器级别的支持。最早的努力当数 “Web Component” 规范说明 circa 2011 的出现,并在同年的 Fronteers Conference 大会上由 Alex Russell 将之宣之于众。该 Web Component 规范的产生和发展,旨在提供一种权威的、浏览器能理解的方式来创建组件。

Web Components 是一系列 Web 技术的集合,主要包括 Shadow DOM、Custom Elements、HTML templates、HTML Import(废弃,HTML Modules替换)。

主要的技术与兼容性

Custom elements:可重用网络组件。

HTML 现行标准缺乏自动关联 JS 行为和标记的方法。自定义元素使 HTML 变得现代化;补充了缺少的部件,并将结构与行为相结合。 如果 HTML 无法为问题提供解决方案,我们可以创建自定义元素来解决。 自定义元素在保留 HTML 优点的同时为浏览器带来新功能。

  1. 自定义元素的名称必须包含短横线 (-)。因此, 等均为有效名称,而 则为无效名称。这一要求使得 HTML 解析器能够区分自定义元素和常规元素。它还可确保向 HTML 添加新标记时的向前兼容性。
  2. 您不能多次注册同一标记。否则,将产生 DOMException。让浏览器了解新标记后,它就这样定了下来。您不能撤回。
  3. 自定义元素不能自我封闭,因为 HTML 仅允许少数元素自我封闭。必须编写封闭标记 ()。

// Or use an anonymous class if you don't want a named constructor in current scope. window.customElements.define('app-drawer', class extends HTMLElement {...});

``` html
<app-drawer></app-drawer>

customElements.define('fancy-app-drawer', FancyDrawer);

- 扩展原生 HTML 元素
``` javascript
// See https://html.spec.whatwg.org/multipage/indices.html#element-interfaces
// for the list of other DOM interfaces.
class FancyButton extends HTMLButtonElement {
  constructor() {
    super(); // always call super() first in the constructor.
    this.addEventListener('click', e => this.drawRipple(e.offsetX, e.offsetY));
  }

  // Material design ripple animation.
  drawRipple(x, y) {
    let div = document.createElement('div');
    div.classList.add('ripple');
    this.appendChild(div);
    div.style.top = `${y - div.clientHeight/2}px`;
    div.style.left = `${x - div.clientWidth/2}px`;
    div.style.backgroundColor = 'currentColor';
    div.classList.add('run');
    div.addEventListener('transitionend', e => div.remove());
  }
}

customElements.define('fancy-button', FancyButton, {extends: 'button'});
<!-- This <button> is a fancy button. -->
<button is="fancy-button" disabled>Fancy button!</button>

扩展原生元素时,对 define() 的调用会稍有不同。所需的第三个参数告知浏览器要扩展的标记。这很有必要,因为许多 HTML 标记均使用同一 DOM 接口。例如,<section>、<address> 和 <em>(以及其他)都使用 HTMLElement;<q> 和 <blockquote> 则使用 HTMLQuoteElement;等等。指定 {extends: 'blockquote'} 可让浏览器知道您创建的是增强的 <blockquote> 而不是 <q>。有关 HTML DOM 接口的完整列表,请参阅 HTML 规范。

自定义元素提供了一种新工具,可让我们在浏览器中定义新 HTML 标记并创建可重用的组件。 将它们与 Shadow DOM 和