什么是web componets, 它的出现是为了什么?

web components旨在提供一套制作可重用的封装性好的自定义元素的标准。

它包括四部分:

customElements -- 这是一个基于CustomeElementRegistry类生成的对象,用于注册自定义元素,如customElements.define('my-popup', MyPop), 并返回已注册的自定义元素的信息。经过注册的元素就可以直接在html页面上像普通元素那样使用了,如<my-popup/>

shadow DOM -- 影子DOM

HTML template -- HTML模板

HTML import -- HTML导入

customElements.define用于注册自定义元素,那什么是自定义元素呢?

自定义元素即为一个class,在这个class里添加各种内置的元素并实现一些逻辑。如果想在页面上使用这个自定义元素,需要用CustomElementRegistry 的define来注册一下。

自定义元素有两种

  1 autonomous custom elements

  extends HTMLElement, 可以通过<popup-info>或doducment.createElement("popup-info")引入到页面

  注册: customElements.define("popup-info", PopupInfo);

  2 customized built-in elements

  继承自基础的html elements,比如div /p/ span等,需要添加is属性来引入到页面,<p is="word-count">或 document.createElement("p", {is:"word-count"})

  注册: customElements.define('expanding-list', ExpandingList, {extends:"ul"});

  很明显的看出来,customize built-in elements注册时,需要提供第三个参数,来表明是继承自谁

自定义元素的生命用期:

  • connectedCallback:当 custom element首次被插入文档DOM时,被调用。
  • disconnectedCallback:当 custom element从文档DOM中删除时,被调用。
  • adoptedCallback:当 custom element被移动到新的文档时,被调用。
  • attributeChangedCallback: 当 custom element增加、删除、修改自身属性时,被调用。这个回调需要自定义组件提示 static get observedAttributes(){return ['属性名','属性名',...];}。如果在组件还没 append到某元素上,此时setAttribute也会触发该事件。

这些都可以在自定义元素的class里直接引入来针对不同的阶段进行相应的业务处理。

Shadow DOM

它是document node的一种。对保证组件的独立,使其行为、样式、事件等不受外部的影响起关键作用。它给自定义组件里的元素提供了一个隐蔽的分离出来的DOM.

与Shadow DOM相关的几个术语:

  • shadow host 是一个普通的dom元素,用来安放shdow dom
  • shadow tree dom树
  • shadow boundary shadow dom的边界,表示shadow dom结束,regular dom开始
  • shadow root shadow tree的根

shadow DOM的基本用法

this.attachShadow({mode:'open'}),将shadow root加到自定义元素上。mode有两个值:open和closed。open的话,在外边也可以访问到组件的shadowRoot,closed的正好相反.

let myShadowDom = myCustomElem.shadowRoot;

 mode为open时myShadowDom可以取到值,并能对里边的元素做操作。mode为close时myShadowDom为null; 

function updateStyle(elem) {
const shadow = elem.shadowRoot; // 访问自定义组件的shadow root
shadow.querySelector('style').textContent = `
div {
width: ${elem.getAttribute('l')}px;
height: ${elem.getAttribute('l')}px;
background-color: ${elem.getAttribute('c')};
}
`; // shadow root有跟document类似的方法如getElementById,querySelector等
}

  

slot和template

在shadow dom中引入slot来增加灵活性。搭配使用template效果更佳。

slot让用户可给向自定义组件里添加自己的标签元素。它通过name属性来指定一个slot,所以组件内的slot的name要唯一。

<template>标签里的代码片断(DocumentFragment)不会被rend到页面上,只能通过javascript的Node.cloneNode克隆出新的DocumentFragment然后后再appendChild或是insertBefore来加来到dom树上。

template里的documentFragment通过HTMLTemplateElement.content来取得。

<template id="element-details-template">
<style>
details {font-family: "Open Sans Light",Helvetica,Arial}
.name {font-weight: bold; color: #217ac0; font-size: 120%}
h4 { margin: 10px 0 -8px 0; }
h4 span { background: #217ac0; padding: 2px 6px 2px 6px }
h4 span { border: 1px solid #cee9f9; border-radius: 4px }
h4 span { color: white }
.attributes { margin-left: 22px; font-size: 90% }
.attributes p { margin-left: 16px; font-style: italic }
</style>
<details>
<summary>
<span>
<code class="name"><<slot name="element-name">NEED NAME</slot>></code> <!--slot->
<i class="desc"><slot name="description">NEED DESCRIPTION</slot></i> <!--slot->
</span>
</summary>
<div class="attributes">
<h4><span>Attributes</span></h4>
<slot name="attributes"><p>None</p></slot> <!--slot ->
</div>
</details>
<hr>
</template>

  

customElements.define('element-details',
class extends HTMLElement {
constructor() {
super(); // constructor里先写上super,this才能被赋值
var template = document
.getElementById('element-details-template')
.content;// template可以通过dom的方法来取到,它的content属性返回的就是内部的DocumentFragment
const shadowRoot = this.attachShadow({mode: 'open'}) // 自定义组件首先要创建shadow,通过appendChild来往shadow里添加标签元素
.appendChild(template.cloneNode(true));
}
})

  

<element-details>
<span slot="element-name">slot</span> <!--通过给标签添加slot="slotName"来将这个标签填充到自定义标签里->
<span slot="description">A placeholder inside a web
component that users can fill with their own markup,
with the effect of composing different DOM trees
together.</span>
<dl slot="attributes"> <!--如果不给名称为attribute的slot写标签的话,会用自定义组件里的该slot内的标签->
<dt>name</dt>
<dd>The name of the slot.</dd>
</dl>
</element-details>

还有一个与此相关的css伪类:define :host :host-context,方法,可以用到时再学习

总结

实现web componets的步骤与方法如下:

https://developer.mozilla.org/zh-CN/docs/Web/Web_Components

学习web components的更多相关文章

  1. web Components 学习之路

    就目前而言,纯粹的Web Components在兼容性方面还有着较为长远的路,这里做个记录总结,以纪念自己最近关于Web Components的学习道路. 参考教材 JavaScript 标准参考教程 ...

  2. 【shadow dom入UI】web components思想如何应用于实际项目

    回顾 经过昨天的优化处理([前端优化之拆分CSS]前端三剑客的分分合合),我们在UI一块做了几个关键动作: ① CSS入UI ② CSS作为组件的一个节点而存在,并且会被“格式化”,即选择器带id前缀 ...

  3. Web Components之Custom Elements

    什么是Web Component? Web Components 包含了多种不同的技术.你可以把Web Components当做是用一系列的Web技术创建的.可重用的用户界面组件的统称.Web Com ...

  4. 【转】Facebook React 和 Web Components(Polymer)对比优势和劣势

    原文转自:http://segmentfault.com/blog/nightire/1190000000753400 译者前言 这是一篇来自 StackOverflow 的问答,提问的人认为 Rea ...

  5. Facebook React 和 Web Components(Polymer)对比优势和劣势

    目录结构 译者前言 Native vs. Compiled 原生语言对决预编译语言 Internal vs. External DSLs 内部与外部 DSLs 的对决 Types of DSLs - ...

  6. Fiori Fundamentals和SAP UI5 Web Components

    这周有位同事邀请我给团队讲一讲SAP技术的演进历史,所以我准备了下面几个主题来介绍. 其中SAP的技术回顾和演进,我的思路就是从前后台两方面分别介绍. 我画了一张非常简单的图: 去年5月我写过一篇文章 ...

  7. Web Components 入门实例教程

    转自阮一峰http://www.ruanyifeng.com/blog/2019/08/web_components.html 组件是前端的发展方向,现在流行的 React 和 Vue 都是组件框架. ...

  8. Web API之Web Components

    本文参考<你的前端框架要被web组件替代了>. 于2011年面世的Web Components是一套功能组件,让开发者可以使用 HTML.CSS 和 JavaScript 创建可复用的组件 ...

  9. Lightning Web Components 安装试用(一)

    Lightning Web Components 简称(lwc) 是一个快速企业级的web 组件化解决方案,同时官方文档很全,我们可以完整的 学习lwc 项目结构 使用npx 官方提供了一个creat ...

随机推荐

  1. U面经Prepare: Print Binary Tree With No Two Nodes Share The Same Column

    Give a binary tree, elegantly print it so that no two tree nodes share the same column. Requirement: ...

  2. linux----------linux下安装rar和unrar命令

    1.wget http://www.rarlab.com/rar/rarlinux-x64-4.2.0.tar.gz 2.tar xf rarlinux-x64-4.2.0.tar.gz    解压下 ...

  3. 003-单例OR工厂模式

    单例模式:DbContextFactory.cs using CZBK.ItcastOA.Model; using System; using System.Collections.Generic; ...

  4. 004-CSS怎样让背景充满整个屏幕

    <!doctype html><html><body> ...Your content goes here...</body></html> ...

  5. windows之电脑开机出现 this product is covered by one or more of the following prtents

    电脑开机出现 this product is covered by one or more of the following prtents 有次意外断电后就每次都出现这个提示,然后要等检查完才能进入 ...

  6. Hashtable几种常用的遍历方法

    Hashtable 在System.Collection是命名空间李Hashtable是程序员经常用到的类,它以快速检索著称,是研发人员开发当中不可缺少的利器. Hashtable表示键/值对的集合, ...

  7. Scala字节数组转换为数字

    1. 2个字节数组转换为整数 def bytes2uint8(_bytes: Array[Byte], _offset: Int): Int = { val b0 = _bytes(_offset) ...

  8. CentOS7 安装 MySQL8.0

    [1]安装步骤过程 (1)yum仓库下载MySQL 命令:yum localinstall https://repo.mysql.com//mysql80-community-release-el7- ...

  9. linux find命令中-print0和xargs中-0的用法

    linux find命令中-print0和xargs中-0的用法. 1.默认情况下, find命令每输出一个文件名, 后面都会接着输出一个换行符 ('\n'), 因此find 的输出都是一行一行的: ...

  10. js惰性函数

    假设我们需要写一个函数,返回首次调用该方法的时间,注意是首次. 1.普通函数,首先定义一个全局变量 t var t; function(){ if(t) return t; t = new Date( ...