iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 25
1

插槽是什麼?

插槽,也就是 slot,是元件的一塊 HTML 模板,這塊模板顯示不顯示、以及怎樣顯示由父 元件來決定。實際上,一個 slot 最核心的兩個問題在這裡就點出來了,是顯示不顯示和怎樣顯示。

由於插槽是一塊模板,所以,對於任何一個元件,從模板種類的角度來分,其實都可以分為非插槽模板和插槽模板兩大類。非插槽模板指的是html模板,比如'<div><span><ul><table>'這些,非插槽模板的顯示與隱藏以及怎樣顯示由元件自身控制;插槽模板是 slot,它是一個空殼子,因為它的顯示與隱藏以及最後用什麼樣的 html 模板顯示由父元件控制。但是插槽顯示的位置卻由子元件自身決定,slot 寫在元件 template 的什麼位置,父元件傳過來的模板將來就顯示在什麼位置。

slot 使用方法

我們先來看看有使用與沒使用 slot 的差別:
無使用 slot:

<div id="app">
    <no-slot-component>
        我想顯示出來,但我會被 template 洗掉 QQ
    </no-slot-component>
</div>
<script type="text/x-template" id="noSlotComponent">
    <div class="alert alert-warning">
        <h6>我是一個元件</h6>
        <p>
            這沒有插槽,我把先前的內容洗掉了。
        </p>
    </div>
</script>
Vue.component('no-slot-component', {
    template: '#noSlotComponent',
});
var app = new Vue({
    el: '#app',
    data: {}
});

https://ithelp.ithome.com.tw/upload/images/20190926/20109609j6Aeicf3QZ.png

我們可以發現在 HTML 裡 <no-slot-component></<no-slot-component> 裡面包的內容沒有顯示,主要的原因是他被我們定義好的子元件下的 template 給取代掉了,但是我們有用 slot就可以避免掉。

有使用 slot

<div id="app">
    <has-slot-component>
        我可以顯示出來惹ヽ(✿゚▽゚)ノ
    </has-slot-component>
</div>
<script type="text/x-template" id="hasSlotComponent">
    <div class="alert alert-warning">
        <h6>我是一個元件</h6>
        <p>
            有 slot 好夥伴,我不會洗你 der
        </p>
        
        <!-- 這裡放了 slot -->
        <slot></slot>
    </div>
</script>
Vue.component('has-slot-component', {
    template: '#hasSlotComponent',
})

var app = new Vue({
    el: '#app',
    data: {}
});

https://ithelp.ithome.com.tw/upload/images/20190926/20109609DI4XptZ9AN.png

slot 種類目前可分為三種

單個插槽(Single Slot)| 默認插槽| 匿名插槽

首先是單個插槽,單個插槽是 vue 的官方叫法,但是其實也可以叫它默認插槽,或者與具名插槽相對,我們可以叫它匿名插槽。因為它不用設置 name 屬性。

單個插槽可以放置在元件的任意位置,但是就像它的名字一樣,一個元件中只能有一個該類插槽。相對應的,具名插槽就可以有很多個,只要名字(name屬性)不同就可以了。

最一開始的範例就是 single slot<sloy></sloy> 會去接收父元件所指定的資料,如果沒有指令資料,則會顯示原本寫在子元件中 <slot></slot> 內的預設資料。

範例:

<div id="app">
    <p>當父元件有指定資料時:<child>HELLO WORLD</child></p>
    <p>當父元件沒有指定資料時:<child></child></p>
</div>
Vue.component('child', {
    template: '<span><slot>This is a default single slot.</slot></span>'
})

new Vue ({
    el: '#app'
})

https://ithelp.ithome.com.tw/upload/images/20190926/20109609pBIXpFF0V9.png

具名插槽(Named Slots)

匿名插槽沒有 name 屬性,所以是匿名插槽,那麼,插槽加了 name 屬性,就變成了具名插槽。具名插槽可以在一個元件中出現N次,出現在不同的位置。slot 可以使用 name 屬性加上名稱,這樣父元件就能指定要將資料放入哪個 slot 中。

<div id="app">  
  <box>
    <p slot="section1">第一段</p>
    <p slot="section2">第二段</p>
    <p>其他內容</p>
    <p>很多其他內容</p>
  </box>
</div>
Vue.component('box', {
  template: `
  <div>
    <slot name="section1"></slot>
    <slot></slot>
    <slot name="section2"></slot>
  </div>`
})

new Vue({
  el: '#app'
})

https://ithelp.ithome.com.tw/upload/images/20190926/20109609kaBFT4O7D3.png

作用域插槽(Scoped Slots)

slot 可以將資料傳遞到父元件,跟 props 傳遞資料的用法很像。

我們可以將要傳遞的資料放入子元件 slot 下的 text,然後父元件那邊用 scope 代表這是給Scoped Slots使用的,props 用來保存從子元件傳遞過來的資料。

<div id="app">
    <child>
        <template scope="props">
            <p>{{ props.text }}</p>
        </template>
    </child>
</div>
Vue.component('child', {
        template: `<div>
                        <slot text="This is a text from slot."></slot>  
                    <div>`
})

new Vue ({
    el: '#app'
})

參考資料

Day18 - [Components] 插槽(Slot)
Vue.js (9.2) - 元件(Component)
Vue.js: Slot
深入理解vue中的slot與slot-scope


上一篇
Vue 24 Component - 元件組合與溝通 [2]
下一篇
Vue 26 使用 is 動態元件 Dynamic Componen
系列文
學習 vue 30天30

尚未有邦友留言

立即登入留言