你可能聽過一些框架例如:Vue/React,你也可能會知道一些組件庫例如: Element-UI/Ant Design.
拿Vue舉例,每一個.vue文件就是一個組件,其中每一個.vue文件中都會有一個模板<template>,最終代碼會將這些模板壓縮打包在一起形成一個.html文件
拿Element來說,每一個組件就是一個Web Component,可以多個合用,多次復用!
對比來說,Web Component就像是一個.vue文件,可復用/拓展性強!
直接上手,我們來寫一個最基本的Web Component!
<el-dialog></el-dialog>
仿照Element-UI組件,我們自定義一個HTML標籤,這就是一個自定義元素.
這裡要注意:自定義元素名稱要求在其中使用破折號,不能只是一個單詞!
自定義元素有了,接下來我們要定義一個javascript類,用來擴展HTMLElement類.
<script>class ElDialog extends HTMLElement { constructor() { super(); }}</script>以上代碼包括了:
1.定義一個ElDialog類繼承了HTML元素的特性
2.constructor()調用這個類
3.super()建立正確的原型鏈.
4.你可以在這裡使用javascript語法
Web文檔上自定義元素的控制者是CustomElementRegistry對象-該對象允許您在頁面上註冊自定義元素,返回有關已註冊哪些自定義元素的信息,等等.
要在頁面上註冊自定義元素,請使用CustomElementRegistry.define()方法.
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> <div>這是一個標題</div> <div>這是內容</div> </div> ` this.append(this.obj) }}window.customElements.define('el-dialog', ElDialog);</script></body>1.定義一個javascript函數render(),這個函數在javascript類創建時調用
2.這個函數創建了一個<div></div>元素
3.使用模板字符串向創建的這個div元素中插入了HTML元素,
4.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> <div>${ this._data.title }</div> <div>${ this._data.content }</div> </div> ` this.append(this.obj) } } window.customElements.define('el-dialog', ElDialog);</script></body>哇喔~~~現在數據已經動態渲染出來了,使用谷歌瀏覽器打開看一下,是不是很酷!使用上面的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結構:
有模板<template>, 有樣式<style>, 有腳本<script>
哪裡需要哪裡調用,只需調用<el-dialog>自定義元素就行了
數據放在自定義元素的屬性值中, 是不是感覺和 vue 中的 slot 插槽類似?
將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組件就已經完成了, 是不是很簡單Web組件是一套不同的技術,允許您創建可重用的自定義元素(其功能與其他代碼封裝在一起),並在Web應用程式中使用它們.
使用簡單, 能夠提升開發效率!
Firefox(版本63),Chrome和Opera中默認支持Web組件。
Safari支持許多Web組件功能,但少於上述瀏覽器。
但是我們依舊可以使用一些第三方庫實現支持!
接下來, 讓我們靜待佳音,相信在不久的將來Web Component將會普及!