什么插槽
官網(wǎng)說明:
在 2.6.0
中,我們?yōu)榫呙宀酆妥饔糜虿宀垡肓艘粋€新的統(tǒng)一的語法 (即 v-slot
指令)缘圈。它取代了 slot
和 slot-scope
這兩個目前已被廢棄但未被移除且仍在文檔中的特性砰苍。新語法的由來可查閱這份 RFC悬蔽。
簡單的概念:插槽,也就是
slot
舱痘,是組件的一塊HTML
模板徘钥,這塊模板顯示不顯示衔蹲、以及怎樣顯示由父組件來決定。slot
最核心的是顯示不顯示
和怎樣顯示
呈础。非插槽模板
html
模板:
指的是div舆驶、span、ul而钞、table
這些沙廉,非插槽模板的顯示與隱藏以及怎樣顯示由插件自身控制;插槽模板
slot
它是一個空殼子臼节,因為它顯示與隱藏
以及最后用什么樣的html模板顯示
由父組件控制撬陵。但是插槽顯示的位置
確由子組件自身
決定,slot
寫在組件template
的哪塊网缝,父組件傳過來的模板將來就顯示在哪塊巨税。
單個插槽|默認插槽 | 匿名插槽
概念:
單個插槽是vue
的官方叫法,是默認插槽粉臊,也是匿名插槽草添。因為它不用設(shè)置name
屬性。
單個插槽维费, 一個組件中只能有一個該類插槽。具名插槽就可以有很多個促王,只要名字(name
屬性)不同就可以了犀盟。樣例:
如果父模板傳遞了值過去,則插槽占位處顯示父組件傳遞過去的值蝇狼,否則默認為子組件插槽的內(nèi)容阅畴,一般情況為空。
父模板
<div class="parent">
<h3>這里是父組件</h3>
<alert-box>有bug發(fā)生</alert-box>
<alert-box>有一個警告</alert-box>
<alert-box></alert-box>
</div>
子組件
Vue.component('alert-box', {
template: `
<div> <strong>ERROR:</strong>
<slot>子組件插槽默認內(nèi)容</slot>
</div>
`
});
展示結(jié)果:
ERROR: 有bug發(fā)生
ERROR: 有一個警告
ERROR: 子組件插槽默認內(nèi)容
<template>
<div class="parent">
<h3>這里是父組件</h3>
<child>
<h4>這里是子組件中插槽占位處要展示的內(nèi)容</h4>
<div class="tmpl">
<span>菜單1</span>
<span>菜單2</span>
</div>
</child>
</div>
</template>
子組件
<template>
<div class="child">
<h3>這里是子組件</h3>
<slot></slot>
</div>
</template>
具名插槽
- 概念:
插槽加了name
屬性迅耘,具名插槽可以在一個
組件中出現(xiàn)N次
贱枣。出現(xiàn)在不同的位置
〔ǎ總之纽哥,存在多個具名插槽的情況下,只需要找準該slot="name"
下的slot
即可栖秕,將對應(yīng)的父組件內(nèi)容傳遞到子組件slot占位處
春塌。父組件通過html
模板上的slot
屬性關(guān)聯(lián)具名插槽。沒有slot屬性的html
模板默認關(guān)聯(lián)匿名插槽。 - 樣例:
父組件
<base-layout>
<p slot='header'>標題信息</p>
<p>主要內(nèi)容1</p>
<p>主要內(nèi)容2</p>
<p slot='footer'>底部信息</p>
</base-layout>
子組件:
Vue.component('base-layout', {
template: `
<div>
有name的插槽可以在該組件中存在多次
<header><slot name='header'></slot></header>
<main> <slot></slot></main>
<footer><slot name='footer'></slot></footer>
</div>
`
});
展示結(jié)果:
標題信息
主要內(nèi)容1
主要內(nèi)容2
底部信息
作用域插槽 | 帶數(shù)據(jù)的插槽
作用域插槽:在slot
上面綁定數(shù)據(jù)只壳。自 2.6.0 起有所更新俏拱。已廢棄的使用 slot-scope
特性的語法。官網(wǎng)介紹新版
slot-scope
聲明了被接收的prop
對象會作為 slotProps
變量存在于 <template>
作用域中吼句。你可以像命名JavaScript
函數(shù)參數(shù)一樣隨意命名 slotProps
<fruit-list :list='list'>
<template slot-scope='slotProps'>
<strong v-if='slotProps.info.id==3' class="current">
{{slotProps.info.name}}
</strong>
</template>
</fruit-list>
Vue.component('fruit-list', {
props: ['list'],
template: `
<div>
<li :key='item.id' v-for='item in list'>
<slot :info='item'>{{item.name}}</slot>
</li>
</div>
`
});
var vm = new Vue({
el: '#app',
data: {
list: [{
id: '1',
name: 'apple'
}, {
id: '2',
name: 'orange'
}, {
id: '3',
name: 'banana'
}
]
}
});
結(jié)果:
apple
orange
banana
2.6.0+官網(wǎng)寫法
將包含所有插槽prop
的對象命名為 slotProps
名字任意取锅必。
<current-user>
<template v-slot:default="slotProps">
{{ slotProps.user.firstName }}
</template>
</current-user>
<span>
<slot v-bind:user="user">
{{ user.lastName }}
</slot>
</span>
注意默認插槽的縮寫語法不能和具名插槽混用,因為它會導(dǎo)致作用域不明確:
<!-- 無效惕艳,會導(dǎo)致警告 -->
<current-user v-slot="slotProps">
{{ slotProps.user.firstName }}
<template v-slot:other="otherSlotProps">
slotProps is NOT available here
</template>
</current-user>
- 只要出現(xiàn)多個插槽搞隐,請始終為所有的插槽使用完整的基于 <template> 的語法:
<current-user>
<template v-slot:default="slotProps">
{{ slotProps.user.firstName }}
</template>
<template v-slot:other="otherSlotProps">
...
</template>
</current-user
解構(gòu)插槽Prop
- 作用域插槽的內(nèi)部工作原理是將你的插槽內(nèi)容包括在一個傳入單個參數(shù)的函數(shù)里,這意味著 v-slot 的值實際上可以是任何能夠作為函數(shù)定義中的參數(shù)的 JavaScript 表達式尔艇。
function (slotProps) {
// 插槽內(nèi)容
}
<current-user v-slot="{ user }">
{{ user.firstName }}
</current-user>
重命名
<current-user v-slot="{ user: person }">
{{ person.firstName }}
</current-user>
具名插槽
跟 v-on
和 v-bind
一樣尔许,v-slot
也有縮寫,即把參數(shù)之前的所有內(nèi)容(v-slot:)
替換為字符#
终娃。例如v-slot:header
可以被重寫為 #header
<base-layout>
<template #header>
<h1>Here might be a page title</h1>
</template>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
<template #footer>
<p>Here's some contact info</p>
</template>
</base-layout>
- 然而味廊,和其它指令一樣,該縮寫只在其有參數(shù)的時候才可用棠耕。這意味著以下語法是無效的:
<!-- 這樣會觸發(fā)一個警告 -->
<current-user #="{ user }">
{{ user.firstName }}
</current-user>
- 如果你希望使用縮寫的話余佛,你必須始終以明確插槽名取而代之:
<current-user #default="{ user }">
{{ user.firstName }}
</current-user>