這篇文章為大家帶來了關於Slots的相關知識,Slots 的作用就是給模板元素傳值,增強模板元素的靈活性和通用性,希望對大家有幫助。
熟悉 Vue 的同學應該都知道」插槽(slot)「的概念,透過使用插槽可以讓頁面內容的組織更加靈活。
在 Web Components 體系中也有插槽的概念,今天我們就來具體了解一下 Slots,本文主要包含以下內容:
<template> <p>MY CARD</p> <p> My name is 编程三昧。 </p></template>既然是模板,那就意味著在很多地方都會使用到它,但是,這裡會存在一個問題:
所有使用這個模板的地方都將顯示模板中的內容,即並不是所有人的名字都叫”編程三昧“ 。
在這種情況下,叫其他名字的人是沒法使用這個模板的,顯然,這就和使用模板的初衷相違背了,這個模板的使用範圍太過狹小,不存在通用性。 想要使得這個範本具有通用性,其關鍵點在於.details 中顯示的內容是否具有通用性。
<!--在模板中使用 slot 进行占位--><template> <p>MY CARD</p> <p> My name is <slot>编程三昧</slot>。 </p></template><!--在使用上面模板的自定义元素中给 slot 传值--><my-card> <span>插槽传值</span></my-card><my-card> <span>web Components</span></my-card>其對應的JS 程式碼如下:
class MyCard extends HTMLElement { constructor () { super(); const template = document.getElementById('cardTmp'); const templateContent = template.content; this.attachShadow({mode: 'open'}).appendChild( templateContent.cloneNode(true) ); }}customElements.define('my-card', MyCard);實現效果:
透過上面的例子,我們可以用一句話總結Slots 的作用:
Slots 的作用就是給模板元素傳值,增強模板元素的彈性和通用性。
Slots 的相關特性對於 Slots 的相關特性,我透過問答的形式逐一解釋。 Slots 的 name 屬性有什麼作用? 帶有指定 name 的 Slots 稱為 」具名插槽“,name 是 slot 的唯一標識。 在引入插槽內容的元素上需要使用與Slots.name 值相同的 slot 屬性。看下面的程式碼:
<template> <p>MY CARD</p> <p> My name is <slot>19</slot>。 </p></template><my-card> <span>编程三昧</span></my-card><my-card> <span>web Components</span></my-card><script> class MyCard extends HTMLElement { constructor () { super(); const template = document.getElementById('cardTmp'); const templateContent = template.content; this.attachShadow({mode: 'open'}).appendChild( templateContent.cloneNode(true) ); } } customElements.define('my-card', MyCard);</script>運行效果: 因為傳入的slot 屬性值和Slots 的name 屬性值對不上,所以Slots 未被插入。
傳值時的 slot 屬性值必須和 Slots 的 name 屬性值一致。不傳值給 Slots 會怎樣? 將上面兩個自訂元素
my-card 中的span 元素去掉,不傳任何值,也就是改成這樣:
<my-card></my-card>運行後的效果: 可以看到,
如果不給Slots 傳值,那麼Slots 會顯示它自己預設的內容。
其實結合以上兩點,還可以得到一個結論:如果有引用 Slots ,那就只有對應 name 的 Slots 內容會被顯示,其餘的 Slots 都不顯示。
正常 DOM 中可以使用 Slots 嗎? 這裡的」正常 DOM「 是相對於 Shadow DOM 來說的,指的是頁面所在的文件物件。 程式碼如下:<slot>Slots 预设值</slot><p>bcsm</p>顯示如下: #總結:
正常DOM 中使用Slots,它會直接渲染在頁面上,切不具備插槽效果。
Slots 是不是必須用在 Templates 中? 我們前面看到的例子中,Slots 是在 Templates 中,那是不是意味著 Slots 必須用在 Templates 中才能生效呢? 因為已經驗證過在正常DOM 中的Slots 是無效的,所以我們在Shadow DOM 中做個測試,程式碼如下:<h1>不在 Templates 中使用 Slots</h1> <p> <slot>这是 Slots 预设值</slot> </p> <my-paragraph> <span>编程三昧</span> </my-paragraph> <script> class MyParagraph extends HTMLElement { constructor () { super(); const template = document.getElementById('templ'); this.attachShadow({mode: 'open'}).appendChild( template.cloneNode(true) ); } } customElements.define('my-paragraph', MyParagraph); </script>顯示效果如下: #從顯示效果可以看到,將包含Slots 的正常DOM 節點在追加到Shadow DOM 後,Slots 顯示傳入的值,也就是說Slots 是生效了的。 總結:
Slots 在 Shadow DOM 中就可生效,並非一定要用在 Templates 中。
一個自訂元素中可以使用多個同名 Slots 嗎? 看程式碼:<template> <p>MY CARD</p> <p> My name is <slot>编程三昧</slot>。 </p></template><my-card> <span>插槽传值1</span> <span>插槽传值2</span></my-card><script> class MyCard extends HTMLElement { constructor () { super(); const template = document.getElementById('cardTmp'); const templateContent = template.content; this.attachShadow({mode: 'open'}).appendChild( templateContent.cloneNode(true) ); } } customElements.define('my-card', MyCard);</script>顯示效果: #結論:
一個Slots 可以接收多個傳入值,且都會解析顯示出來。
上面的例子中,所有给 Slots 传值的元素都是自定义元素的子元素,那是不是非直接子元素不行呢?
代码如下:
<template> <p>MY CARD</p> <p> My name is <slot>编程三昧</slot>。 </p></template><my-card> <p> <span>插槽传值1</span> </p></my-card><script> class MyCard extends HTMLElement { constructor () { super(); const template = document.getElementById('cardTmp'); const templateContent = template.content; this.attachShadow({mode: 'open'}).appendChild( templateContent.cloneNode(true) ); } } customElements.define('my-card', MyCard);</script>
运行效果(传值失效):
结论:给 Slots 传值的元素必须是自定义元素的直接子元素,否则传值失效。
更多编程相关知识,请访问:编程视频!!
以上是一起聊聊Web Components之Slots(實例詳解)的詳細內容。更多資訊請關注PHP中文網其他相關文章!