插槽,也就是 slot,是元件的一塊 HTML 模板,這塊模板顯示不顯示、以及怎樣顯示由父 元件來決定。實際上,一個 slot 最核心的兩個問題在這裡就點出來了,是顯示不顯示和怎樣顯示。
由於插槽是一塊模板,所以,對於任何一個元件,從模板種類的角度來分,其實都可以分為非插槽模板和插槽模板兩大類。非插槽模板指的是html模板,比如'<div>
、<span>
、<ul>
、<table>
'這些,非插槽模板的顯示與隱藏以及怎樣顯示由元件自身控制;插槽模板是 slot,它是一個空殼子,因為它的顯示與隱藏以及最後用什麼樣的 html 模板顯示由父元件控制。但是插槽顯示的位置卻由子元件自身決定,slot 寫在元件 template 的什麼位置,父元件傳過來的模板將來就顯示在什麼位置。
我們先來看看有使用與沒使用 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: {}
});
我們可以發現在 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: {}
});
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'
})
匿名插槽沒有 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'
})
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