您好,登錄后才能下訂單哦!
這篇“Web Components如何實現類Element UI中的Card卡片”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Web Components如何實現類Element UI中的Card卡片”文章吧。
自定義元素(custom element),使用 window.customElements.define
API注冊
Shadow DOM隔離,影藏標記結構、樣式和行為
可以在<template>
中定義標記結構、樣式,多次重用。利用 slot
插槽、命名插槽,可以傳入定制化的結構UI,使用上類似 Vue
中的 slot
插槽
自定義的 HTML 標簽,稱為自定義元素(custom element)。根據規范,自定義元素的名稱必須包含連詞線-
,用與區別原生的 HTML 元素。所以,<com-card>
不能寫成<comcard>
。
<div id="custom-card" class="com-card"> <div class="com-card-head"> <slot name="head"></slot> </div> <div class="com-card-body"> <slot></slot> <div class="link-wrap"> <a class="link" href="" title=" rel="external nofollow" rel="external nofollow" "></a> </div> </div> </div> <script> class ComCard extends HTMLElement { constructor() { super() var tplEle = document.getElementById('custom-card') this.append(tplEle) } } window.customElements.define('com-card', ComCard) </script>
這樣就注冊了瀏覽器可識別渲染的一個自定義元素標簽。
Shadow DOM 是對DOM的一個封裝。可以將標記結構、樣式和行為隱藏起來,并與頁面上的其他代碼相隔離,保證不同的部分不會混在一起,可使代碼更加干凈、整潔。
使用自定義元素的 this.attachShadow()
方法可以開啟 Shadow DOM
。
class ComCard extends HTMLElement { constructor() { super() var shadow = this.attachShadow({mode: 'closed'}) // open var tplEle = document.getElementById('custom-card') shadow.appendChild(tplEle) } } window.customElements.define('com-card', ComCard);
其中參數{ mode: 'closed' }
,表示 Shadow DOM
是封閉的,不允許外部訪問。
因為組件的樣式應該與代碼封裝在一起,只對自定義元素生效,不影響外部的全局樣式。所以,可以把樣式寫在<template>
里面,這樣作為自定義元素結構的基礎可以被多次重用。
<template id="custom-card-template"> <style> .com-card { } </style> <div class="com-card"> </div> </template> <script> class ComCard extends HTMLElement { constructor() { super(); var shadow = this.attachShadow({mode: 'closed'}) // open var tplEle = document.getElementById('custom-card-template') var content = tplEle.content.cloneNode(true) shadow.appendChild(content) } } window.customElements.define('com-card', ComCard); </script>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Web Component</title> <style> * { box-sizing: border-box; } body { font-size: 14px; } .box { padding: 5px 0 30px; } .box .caption { display: none; } .box h2 { text-align: center; } .box li { color: #666; font-size: 14px; line-height: 1.8; margin-top: 15px; } .img { display: block; width: 80%; margin: 0 !important; } .card-head { display: flex; justify-content: space-between; align-items: center; } .card-title { color: #333; font-size: 16px; } .card-head-btn { color: #409eff; cursor: pointer; text-decoration: none !important; } .card-head-btn:hover { text-decoration: none; } </style> </head> <body> <div class="box"> <h2>Web Component</h2> <com-card data-show-head="0" data-url="https://tiven.cn" data-title="天問博客"> <div slot="head" class="card-head"> <div class="card-title">卡片名稱</div> <a class="card-head-btn">操作按鈕</a> </div> <img class="img" src="https://tiven.cn/static/img/kpl-sunwukong-a3Lt-ed2NG9r4NFDm_9DA.jpg" alt="天問"> </com-card> <br> <br> <com-card data-show-head="1" data-url="https://tiven.cn/p/de241e23/" data-title="Vite+Vue3+Vant快速構建項目"> <div slot="head" class="card-head"> <div class="card-title">卡片名稱</div> <a class="card-head-btn" onclick="hello()">操作按鈕</a> </div> <img class="img" src="https://tiven.cn/static/img/kpl-xuance-JqX71qH7aTflHV_gqvhIc.jpg" alt="天問"> <ol> <li>君不見黃河之水天上來,奔流到海不復回。</li> <li>君不見高堂明鏡悲白發,朝如青絲暮成雪。</li> <li>天生我材必有用,千金散盡還復來。</li> </ol> </com-card> </div> <template id="custom-card-template"> <style> .com-card { min-width: 200px; min-height: 100px; border-radius: 4px; border: 1px solid #ebeef5; background-color: #fff; overflow: hidden; color: #303133; transition: .3s; box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); } .com-card-head { padding: 10px 20px; border-bottom: 1px solid #ebeef5; box-sizing: border-box; } .com-card-body { padding: 20px; } .link-wrap { text-align: left; padding-top: 20px; } .link { display: inline-block; height: 42px; line-height: 43px; padding: 0 30px; text-align: center; cursor: pointer; color: #fff; background-color: #409eff; border-color: #409eff; -webkit-appearance: none; box-sizing: border-box; outline: none; transition: .1s; font-weight: 500; -moz-user-select: none; -webkit-user-select: none; -ms-user-select: none; font-size: 14px; border-radius: 4px; text-decoration: none !important; } </style> <div class="com-card"> <div class="com-card-head"> <slot name="head"></slot> </div> <div class="com-card-body"> <slot></slot> <div class="link-wrap"> <a class="link" href="" title=" rel="external nofollow" rel="external nofollow" "></a> </div> </div> </div> </template> <script> class ComCard extends HTMLElement { constructor() { super(); var shadow = this.attachShadow({mode: 'closed'}) // open var tplEle = document.getElementById('custom-card-template') var content = tplEle.content.cloneNode(true) var attrList = Array.from(this.attributes); var props = attrList.reduce((prev, item)=>{ prev[item.name] = item.value return prev }, {}) if (props['data-show-head']!=='1') { var head = content.querySelector('.com-card-head') head.remove() } var urlEle = content.querySelector('.link') if (props['data-url'] && props['data-title']) { urlEle.href = props['data-url'] urlEle.title = props['data-title'] urlEle.innerText = props['data-title'] } else { urlEle.remove() } shadow.appendChild(content) } connectedCallback(){ //在這里發送數據請求(Ajax) console.log('connectedCallback') } //被從文檔DOM中刪除時調用 disconnectedCallback(){ console.log('disconnectedCallback') } //被移動到新的文檔時調用 adoptedCallback(){ console.log('adoptedCallback') } //當增加、刪除、修改自身的屬性時被調用 attributeChangedCallback(){ console.log('attributeChangedCallback') } } window.customElements.define('com-card', ComCard); function hello() { alert('Hello,Web Component') } </script> </body> </html>
最終效果如上圖所示
Vue Component | Web Component |
---|---|
data | 實例屬性 |
props | attributes |
watch | observedAttributes、attributeChangedCallback |
computed | getters |
methods | class methods |
mounted | connectedCallback |
destroyed | disconnectedCallback |
style scoped | template中的style |
template | template |
connectedCallback
:當 custom element首次被插入文檔DOM時,被調用。
disconnectedCallback
:當 custom element從文檔DOM中刪除時,被調用。
adoptedCallback
:當 custom element被移動到新的文檔時,被調用。
attributeChangedCallback
: 當 custom element增加、刪除、修改自身屬性時,被調用。
優點:
瀏覽器原生支持,不需要引入額外的第三方庫
語義化
復用性,移植性高
不同團隊不同項目可以共用組件
缺點:
需要操作DOM
目前瀏覽器兼容性、性能方面不夠友好
和外部css交互比較難
LitElement 是一個快速、輕量級的 Web UI 框架。使用 lit-html
來渲染元素。
Polymer 是一款實用、基于事件驅動、封裝性和交互性強的 Web UI 框架。
Omi 是基于 Web 組件的跨框架跨平臺框架 。移動端 & 桌面 & 小程序。
以上就是關于“Web Components如何實現類Element UI中的Card卡片”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。