Web Components 是个什么样的东西

521 查看

前端组件化这个主题相关的内容已经火了很久很久,angular 刚出来时的 Directive 到 angular2 的 components,还有 React 的components 等等,无一不是前端组件化的一种实现和探索,但是提上议程的 Web Components 标准是个怎样的东西,相关的一些框架或者类库,如 React,Angular2,甚至是 x-tag,polymer 现在实现的组件化的东西和 Web Components 标准差别在哪里?我花时间努力地把现有的 W3C Web Components 文档看了下,然后坚强地写下这些记录。

首先我们需要知道,Web Components 包括了四个部分:

这四部分有机地组合在一起,才是 Web Components。

可以用自定义的标签来引入组件是前端组件化的基础,在页面引用 HTML 文件和 HTML 模板是用于支撑编写组件视图和组件资源管理,而 Shadow DOM 则是隔离组件间代码的冲突和影响。

下边分别是每一部分的笔记内容。

Custom Elements

概述

Custom Elements 顾名思义,是提供一种方式让开发者可以自定义 HTML 元素,包括特定的组成,样式和行为。支持 Web Components 标准的浏览器会提供一系列 API 给开发者用于创建自定义的元素,或者扩展现有元素。

这一项标准的草案还处于不稳定的状态,时有更新,API 还会有所变化,下边的笔记以 Cutsom Elements 2016.02.26 这个版本为准,因为在最新的 chrome 浏览器已经是可以工作的了,这样可以使用 demo 来做尝试,最后我会再简单写一下最新文档和这个的区别。

registerElement

首先,我们可以尝试在 chrome 控制台输入 HTMLInputElement,可以看到是有这么一个东西的,这个理解为 input DOM 元素实例化时的构造函数,基础的是 HTMLElement

Web Components 标准提出提供这么一个接口:

你可以使用 document.registerElement 来注册一个标签,标准中为了提供 namesapce 的支持,防止冲突,规定标签类型(也可以理解为名字)需要使用 - 连接。同时,不能是以下这一些:

  • annotation-xml
  • color-profile
  • font-face
  • font-face-src
  • font-face-uri
  • font-face-format
  • font-face-name
  • missing-glyph

第二个参数是标签相关的配置,主要是提供一个 prototype,这个原型对象是以 HTMLElement 等的原型为基础创建的对象。然后你便可以在 HTML 中去使用自定义的标签。如:

是不是嗅到了 React 的味道?好吧,React 说它自己主要不是做这个事情的。

生命周期和回调

在这个 API 的基础上,Web Components 标准提供了一系列控制自定义元素的方法。我们来一一看下:

一个自定义元素会经历以下这些生命周期:

  • 注册前创建
  • 注册自定义元素定义
  • 在注册后创建元素实例
  • 元素插入到 document 中
  • 元素从 document 中移除
  • 元素的属性变化时

这个是很重要的内容,开发者可以在注册新的自定义元素时指定对应的生命周期回调来为自定义元素添加各种自定义的行为,这些生命周期回调包括了:

  • createdCallback
    自定义元素注册后,在实例化之后会调用,通常多用于做元素的初始化,如插入子元素,绑定事件等。
  • attachedCallback
    元素插入到 document 时触发。
  • detachedCallback
    元素从 document 中移除时触发,可能会用于做类似 destroy 之类的事情。
  • attributeChangedCallback
    元素属性变化时触发,可以用于从外到内的通信。外部通过修改元素的属性来让内部获取相关的数据并且执行对应的操作。

这个回调在不同情况下有对应不同的参数:

  • 设置属性时,参数列表是:属性名称,null,值,命名空间
  • 修改属性时,参数列表是:属性名称,旧值,新值,命名空间
  • 删除属性时,参数列表是:属性名称,旧值,null,命名空间

好了,就上边了解到的基础上,假设我们要创建一个自定义的 button-hello 按钮,点击时会 alert('hello world'),代码如下:

要留意上述代码执行之后才能使用 <button-hello></button-hello>

扩展原有元素

其实,如果我们需要一个按钮,完全不需要重新自定义一个元素,Web Components 标准提供了一种扩展现有标签的方式,把上边的代码调整一下:

然后在 HTML 中要这么使用:

使用 is 属性来声明一个扩展的类型,看起来也蛮酷的。生命周期和自定义元素标签的保持一致。

当我们需要多个标签组合成新的元素时,我们可以使用自定义的元素标签,但是如果只是需要在原有的 HTML 标签上进行扩展的话,使用 is 的这种元素扩展的方式就好。

原有的 createElementcreateElementNS,在 Web Components 标准中也扩展成为支持元素扩展,例如要创建一个 button-hello

标准文档中还有很多细节上的内容,例如接口的参数说明和要求,回调队列的实现要求等,这些更多是对于实现这个标准的浏览器开发者的要求,这里不做详细描述了,内容很多,有兴趣的自行查阅:ngular2,甚至是 x-tag,polymer 现在实现的组件化的东西和 Web Components 标准差别在哪里?我花时间努力地把现有的 W3C Web Components 文档看了下,然后坚强地写下这些记录。

首先我们需要知道,Web Components 包括了四个部分:

这四部分有机地组合在一起,才是 Web Components。

可以用自定义的标签来引入组件是前端组件化的基础,在页面引用 HTML 文件和 HTML 模板是用于支撑编写组件视图和组件资源管理,而 Shadow DOM 则是隔离组件间代码的冲突和影响。

下边分别是每一部分的笔记内容。

Custom Elements

概述

Custom Elements 顾名思义,是提供一种方式让开发者可以自定义 HTML 元素,包括特定的组成,样式和行为。支持 Web Components 标准的浏览器会提供一系列 API 给开发者用于创建自定义的元素,或者扩展现有元素。

这一项标准的草案还处于不稳定的状态,时有更新,API 还会有所变化,下边的笔记以 Cutsom Elements 2016.02.26 这个版本为准,因为在最新的 chrome 浏览器已经是可以工作的了,这样可以使用 demo 来做尝试,最后我会再简单写一下最新文档和这个的区别。

registerElement

首先,我们可以尝试在 chrome 控制台输入 HTMLInputElement,可以看到是有这么一个东西的,这个理解为 input DOM 元素实例化时的构造函数,基础的是 HTMLElement

Web Components 标准提出提供这么一个接口:

你可以使用 document.registerElement 来注册一个标签,标准中为了提供 namesapce 的支持,防止冲突,规定标签类型(也可以理解为名字)需要使用 - 连接。同时,不能是以下这一些:

  • annotation-xml
  • color-profile
  • font-face
  • font-face-src
  • font-face-uri
  • font-face-format
  • font-face-name
  • missing-glyph

第二个参数是标签相关的配置,主要是提供一个 prototype,这个原型对象是以 HTMLElement 等的原型为基础创建的对象。然后你便可以在 HTML 中去使用自定义的标签。如:

是不是嗅到了 React 的味道?好吧,React 说它自己主要不是做这个事情的。

生命周期和回调

在这个 API 的基础上,Web Components 标准提供了一系列控制自定义元素的方法。我们来一一看下:

一个自定义元素会经历以下这些生命周期:

  • 注册前创建
  • 注册自定义元素定义
  • 在注册后创建元素实例
  • 元素插入到 document 中
  • 元素从 document 中移除
  • 元素的属性变化时

这个是很重要的内容,开发者可以在注册新的自定义元素时指定对应的生命周期回调来为自定义元素添加各种自定义的行为,这些生命周期回调包括了:

  • createdCallback
    自定义元素注册后,在实例化之后会调用,通常多用于做元素的初始化,如插入子元素,绑定事件等。
  • attachedCallback
    元素插入到 document 时触发。
  • detachedCallback
    元素从 document 中移除时触发,可能会用于做类似 destroy 之类的事情。
  • attributeChangedCallback
    元素属性变化时触发,可以用于从外到内的通信。外部通过修改元素的属性来让内部获取相关的数据并且执行对应的操作。

这个回调在不同情况下有对应不同的参数:

  • 设置属性时,参数列表是:属性名称,null,值,命名空间
  • 修改属性时,参数列表是:属性名称,旧值,新值,命名空间
  • 删除属性时,参数列表是:属性名称,旧值,null,命名空间

好了,就上边了解到的基础上,假设我们要创建一个自定义的 button-hello 按钮,点击时会 alert('hello world'),代码如下:

要留意上述代码执行之后才能使用 <button-hello></button-hello>

扩展原有元素

其实,如果我们需要一个按钮,完全不需要重新自定义一个元素,Web Components 标准提供了一种扩展现有标签的方式,把上边的代码调整一下:

然后在 HTML 中要这么使用:

使用 is 属性来声明一个扩展的类型,看起来也蛮酷的。生命周期和自定义元素标签的保持一致。

当我们需要多个标签组合成新的元素时,我们可以使用自定义的元素标签,但是如果只是需要在原有的 HTML 标签上进行扩展的话,使用 is 的这种元素扩展的方式就好。

原有的 createElementcreateElementNS,在 Web Components 标准中也扩展成为支持元素扩展,例如要创建一个 button-hello