時間:2023-05-29 00:15:02 | 來源:網(wǎng)站運(yùn)營
時間:2023-05-29 00:15:02 來源:網(wǎng)站運(yùn)營
Web Componets 實(shí)踐報告,原生組件開發(fā):<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title></head><body> <hello-custom></hello-custom> <hello-custom></hello-custom> <hello-custom></hello-custom></body><script> class HelloCustom extends HTMLElement { constructor() { super(); let hello = document.createElement('div'); hello.innerHTML = "測試一下自定義元素" this.append(hello) } } window.customElements.define('hello-custom', HelloCustom);</script></html>
this.append
方法把元素加入當(dāng)前自定義標(biāo)簽。一個自定義標(biāo)簽類就實(shí)現(xiàn)了,然后在全局對象customElements
調(diào)用define
方法注冊我們的組件注意:自定義標(biāo)簽必須是中間有一個連字符,瀏覽器默認(rèn)單個單詞是原生標(biāo)簽,有連字符的為自定義標(biāo)簽<body> <template id="hello"> <p>測試一下hello</p> <a href="">這里是測試的模板</a> </template></body>
var content = hello.content.cloneNode(true);
。class HelloCustom extends HTMLElement { constructor() { super(); let hello = document.getElementById("hello") var content = hello.content.cloneNode(true); this.append(content) } }
<template id="hello"> <style> p { background-color: blue; color: white; } </style> <p>測試一下hello</p> <a href="">這里是測試的模板</a> </template>
<style> #htllo_test { background-color: red; } </style> <template id="hello"> <style> p { background-color: blue; color: white; } </style> <p id="htllo_test">測試一下hello</p> <a href="">這里是測試的模板</a> </template> ``` 外部的css樣式作用到了組件上面,并且權(quán)重更高,把組件內(nèi)部樣式給覆蓋了,原本的藍(lán)色背景,變成了紅色。用過vue的同學(xué)都知道,vue的style標(biāo)簽上面有一個scope屬性,可以防止外部樣式作用到內(nèi)部組件上面,在我們的原生組件上面,我們要怎么實(shí)現(xiàn)呢,這里就用到了三大api中的最后一個,**Shadow DOM(影子DOM)**### Shadow DOM(影子DOM) 所謂的影子dom,見名知意,就是可以屏蔽外部的影響,很簡單吧。我們就不搞那些花里胡哨的說法了,直接開整。 ```js class HelloCustom extends HTMLElement { constructor() { super(); this.shadow = this.attachShadow({mode:'closed'}) // open和closed分別控制是否能被外部js訪問 let hello = document.getElementById("hello") var content = hello.content.cloneNode(true); this.shadow.append(content) } } ``` 可以發(fā)現(xiàn),使用非常的簡單,只需要加入一條代碼 `this.shadow = this.attachShadow({mode:'open'})` 然后在選擇添加的時候把我們的內(nèi)容添加到this.shadow上面就可以了。 再次查看效果,可以發(fā)現(xiàn),外部樣式已經(jīng)無法影響到內(nèi)部,并且,內(nèi)部的細(xì)節(jié)以及被隱藏,無法查看內(nèi)部結(jié)構(gòu)了,這是因?yàn)槲覀冊谑褂胹hadow dom的時候選擇的*mode:closed*,如果選擇open,則為可以查看。它的本質(zhì)是,是否允許外部js直接修改操作組件內(nèi)部dom。<br> 使用了Shadow DOM之后,可以在template中使用Shadow DOM的專用選擇器*host*選擇器,它選擇的是整個template本身。值得注意的是,它必須顯示指定display屬性,否則不可見。 比如鼠標(biāo)劃上自定義元素,左側(cè)無法框選,也無法選中。設(shè)置display之后:```html <template id="hello"> <style> :host { display: block; border: 5px solid gray; } p { background-color: blue; color: white; } </style> <p id="htllo_test">測試一下hello</p> <a href="">這里是測試的模板</a> </template>
class HelloCustom extends HTMLElement { // 生命周期 - created constructor() { super(); console.log('created-被執(zhí)行'); this.shadow = this.attachShadow({ mode: 'closed' }) // open和closed分別控制是否能被外部js訪問 let hello = document.getElementById("hello") var content = hello.content.cloneNode(true); this.shadow.append(content) } // 生命周期 - mounted connectedCallback() { console.log('mounted-被執(zhí)行'); } // 生命周期 - update attributeChangedCallback() { console.log('update-被執(zhí)行'); } // 生命周期 - destory disconnectedCallback() { console.log('被移出') } }
<template id="hello"> <style> :host { display: block; border: 5px solid gray; } p { background-color: blue; color: white; } </style> <p id="htllo_test"></p> <slot>slot default</slot> <slot name="slot1">slot1</slot> <a href="">這里是測試的模板</a> <slot name="slot2">slot2</slot> </template> <hello-custom title="外部傳參測試" id="hello_custom"> <div>我是默認(rèn)slot</div> <div slot="slot1">name slot1</div> </hello-custom>
<hello-custom title="外部傳參測試"></hello-custom>class HelloCustom extends HTMLElement { // 生命周期 - created constructor() { super(); this.shadow = this.attachShadow({ mode: 'closed' }) // open和closed分別控制是否能被外部js訪問 let hello = document.getElementById("hello") var content = hello.content.cloneNode(true); content.querySelector("#htllo_test").innerHTML = this.getAttribute("title") this.shadow.append(content) } }
this.getAttribute
就可以獲取掛載在外部的參數(shù),然后想怎么操作就怎么操作<hello-custom title="外部傳參測試" id="hello_custom"></hello-custom> <button class="test_btn" onclick="test()">測試改變</button>class HelloCustom extends HTMLElement { // 生命周期 - created constructor() { super(); this.shadow = this.attachShadow({ mode: 'closed' }) // open和closed分別控制是否能被外部js訪問 let hello = document.getElementById("hello") this.content = hello.content.cloneNode(true); this.shadow.append(this.content) } attributeChangedCallback(name, oldValue, newValue) { this.shadow.querySelector("#htllo_test").innerHTML = newValue console.log("被執(zhí)行", newValue); } static get observedAttributes() {return ['title', 'l']; } } window.customElements.define('hello-custom', HelloCustom); function test() { let myHello = document.getElementById('hello_custom') myHello.setAttribute("title", "修改后的外部參數(shù)測試" + new Date()) // console.log(myHello); }
需要注意的是,如果需要在元素屬性變化后,觸發(fā) attributeChangedCallback()
回調(diào)函數(shù),你必須監(jiān)聽這個屬性。這可以通過定義observedAttributes()
get函數(shù)來實(shí)現(xiàn),observedAttributes()
函數(shù)體內(nèi)包含一個 return語句,返回一個數(shù)組,包含了需要監(jiān)聽的屬性名稱。static get observedAttributes() {return ['title', 'l']; }
可以看到,已經(jīng)成功得到回調(diào)。function test() { let myHello = document.getElementById('hello_custom') myHello.setAttribute("title", "修改后的外部參數(shù)測試" + new Date()) // console.log(myHello); console.log(myHello.shadowRoot); }
this.shoadow
關(guān)鍵詞:實(shí)踐,報告
客戶&案例
營銷資訊
關(guān)于我們
微信公眾號
版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。