Web Component组件化
1.什么是Web Component?
你可能听过一些框架例如:Vue/React,你也可能会知道一些组件库例如: Element-UI/Ant Design.
拿Vue举例,每一个.vue文件就是一个组件,其中每一个.vue文件中都会有一个模板<template>
,最终代码会将这些模板压缩打包在一起形成一个.html文件
拿Element来说,每一个组件就是一个Web Component,可以多个合用,多次复用!
对比来说,Web Component就像是一个.vue文件,可复用/拓展性强!
直接上手,我们来写一个最基本的Web Component!
2.1.1自定义HTML标签
<el-dialog></el-dialog>
仿照Element-UI组件,我们自定义一个HTML标签,这就是一个自定义元素.
这里要注意:自定义元素名称要求在子其中使用破折号,不能只是一个单词!
2.1.2定义一个javascript类
自定义元素有了,接下来我们要定义一个javascript类,用来扩展HTMLElement类.
<script> class ElDialog extends HTMLElement { constructor() { super(); } } </script>
以上代码包括了:
-
定义一个ElDialog类继承了HTML元素的特性
-
constructor()调用这个类
-
super()建立正确的原型链.
-
你可以在这里使用javascript语法
Web文档上自定义元素的控制者是
要在页面上注册自定义元素,请使用
接下来我们来注册这个自定义元素
window.customElements.define('el-dialog', ElDialog);
这样一来,我们就完成了一个自定义元素的注册了!
But~ 这个自定义元素是空的, 我们向里面加入内容
<body> <el-dialog></el-dialog> <script> class ElDialog extends HTMLElement { constructor() { super(); this.render(); } render() { this.obj = document.createElement('div') this.obj.innerHTML = ` <div class="box"> <div class="title">这是一个标题</div> <div class="content">这是内容</div> </div> ` this.append(this.obj) } } window.customElements.define('el-dialog', ElDialog); </script> </body>
-
定义一个javascript函数
render()
,这个函数在javascript类创建时调用 -
这个函数创建了一个
<div></div>
元素 -
使用模板字符串向创建的这个div元素中插入了HTML元素,
-
this.append(this.obj): 将整个DOM结构插入了自定义元素实例
现在,你已经实现了基本的Web Component!
可是,这些数据是写死的怎么能行呢?
我们来实现动态数据:
<body> <el-dialog title="这是动态标题" content="这是动态内容"></el-dialog> <script> class ElDialog extends HTMLElement { constructor() { super(); // 获得自定义元素的属性 let attr = this.attributes; // 定义数据对象,使用三元表达式 this._data = { title: attr.title ? attr.title.value : '默认的标题', content: attr.content ? attr.content.value : '默认内容' } this.render() } render() { this.obj = document.createElement('div') // 动态渲染数据 this.obj.innerHTML = ` <div class="box"> <div class="title">${ this._data.title }</div> <div class="content">${ this._data.content }</div> </div> ` this.append(this.obj) } } window.customElements.define('el-dialog', ElDialog); </script> </body>
哇喔~~~现在数据已经动态渲染出来了,使用谷歌浏览器打开看一下,是不是很酷!
2.1.3进阶
使用上面的DOM结构,你可能会感觉有点麻烦
别急~
上面我说过 Web Component就像是一个.vue文件,可复用/拓展性强!为什么这么说呢, 一起来看接下来的代码~~~
<body> <el-dialog title="这是动态标题" content="这是动态内容" img="http://wuliwu.top/logo.png" ></el-dialog> <template id="myElDialog"> <style> .box { display: inline-block; text-align: center; border: 1px solid #dedede; padding: 40px; } .title { font-size: 24px; color: #333; } .content { font-size: 16px; color: #666; } </style> <div class="box"> <img> <div class="title"></div> <div class="content"></div> </div> </template> <script> class ElDialog extends HTMLElement { constructor() { super(); var templateElem = document.getElementById('myElDialog'); // 深度克隆 var content = templateElem.content.cloneNode(true); content.querySelector('img').setAttribute('src', this.getAttribute('img')); content.querySelector('.title').innerHTML = this.getAttribute('title') content.querySelector('.content').innerText = this.getAttribute('content') this.appendChild(content); } } window.customElements.define('el-dialog', ElDialog); </script> </body>
哦呵~~~出现了很熟悉的的东西<template>
模板标签, 里面有style样式,有DOM结构
我们来看一下效果图和DOM结构:
这样一看,是不是和.vue文件很像?
-
有模板
<template>
, 有样式<style>
, 有脚本<script>
-
哪里需要哪里调用,只需调用
<el-dialog>
自定义元素就行了 -
数据放在自定义元素的属性值中, 是不是感觉和 vue 中的 slot 插槽类似?
2.1.4 Shadow Dom
将Web Component的代码隐藏起来,DOM与外部DOM隔离,内部任何代码都无法影响外部.
使用方法this.attachShadow()开启Shadow DOM
<script> class ElDialog extends HTMLElement { constructor() { super(); var shadow = this.attachShadow( { mode: 'closed' } ); var templateElem = document.getElementById('myElDialog'); // 深度克隆 var content = templateElem.content.cloneNode(true); content.querySelector('img').setAttribute('src', this.getAttribute('img')); content.querySelector('.title').innerHTML = this.getAttribute('title') content.querySelector('.content').innerText = this.getAttribute('content') shadow.appendChild(content); } } window.customElements.define('el-dialog', ElDialog); </script>
这样,一个完整的Web Component组件就已经完成了, 是不是很简单,没有像vue框架那么复杂.
3.Web Component的好处是什么?
Web组件是一套不同的技术,允许您创建可重用的自定义元素(其功能与其他代码封装在一起),并在Web应用程序中使用它们.
使用简单, 能够提升开发效率!
4.Web Component未来的发展方向如何?
目前而言:
-
Firefox(版本63),Chrome和Opera中默认支持Web组件。
-
Safari支持许多Web组件功能,但少于上述浏览器。
-
Edge正在实施。
-
可以使用一些第三方库实现支持!
接下来, 让我们静待佳音,相信在不久的将来Web Component将会普及!