具名插槽
當(dāng)我們組件需要用到多個(gè)插槽的時(shí)候, 需要用到具名插槽:
// subComponent
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
在向上例中, 具名插槽提供內(nèi)容時(shí), 需要在一個(gè) <template> 元素上使用 v-slot 指令, 并以 v-slot 的參數(shù)的形式提供插槽名稱:
// parentComponent
<sub-component>
<template v-slot="header">
<h1>這里是header的插槽內(nèi)容</h1>
</template>
<p>這里是默認(rèn)插槽的插槽內(nèi)容</p>
<p>And another one.</p>
<template v-slot:footer>
<p>這里是footer的插槽內(nèi)容</p>
</template>
</sub-component>
當(dāng)然, 也可以在一個(gè) <template> 中包裹默認(rèn)插槽的內(nèi)容:
// parentComponent
<sub-component>
<template v-slot="header">
<h1>這里是header的插槽內(nèi)容</h1>
</template>
<template v-slot:default>
<p>這里是默認(rèn)插槽的插槽內(nèi)容</p>
<p>And another one.</p>
</template>
<template v-slot:footer>
<p>這里是footer的插槽內(nèi)容</p>
</template>
</sub-component>
任何的一種寫法都會渲染出:
<div class="container">
<header>
<h1>這里是header的插槽內(nèi)容</h1>
</header>
<main>
<p>這里是默認(rèn)插槽的插槽內(nèi)容</p>
<p>And another one.</p>
</main>
<footer>
<p>這里是footer的插槽內(nèi)容</p>
</footer>
</div>
作用域插槽
有時(shí)候需要讓插槽內(nèi)容能夠訪問到子組件中才有的數(shù)據(jù), 例如在 <user-info> 組件中:
// userInfo
<span>
<slot name="user-info">{{ user.userName }}</slot>
</span>
此時(shí), 在父組件中, 如果想要讓它的后備內(nèi)容顯示用戶的年齡, 以取代用戶名, 如下:
// parentComponent
<current-user>
<template>
{{ user.age }}
</template>
</current-user>
顯然, 這段代碼不會正常的工作, 因?yàn)橹挥?<user-info> 組件中才可以訪問到 user, 而當(dāng)前提供的內(nèi)容是父組件渲染的。
為了讓 user 在父組件的插槽內(nèi)容可以被使用, 可以將 user 作為 <slot> 元素的一個(gè)特性綁定上去:
// userInfo
<span>
<slot name="user-info" v-bind:user="user"></slot>
</span>
綁定在 <slot> 元素上的特性被稱為 插槽prop , 現(xiàn)在在父組件中, 可以給 v-slot 帶一個(gè)值來定義剛才提供的 插槽prop 的名字:
// parentComponent
<user-info>
<template v-slot:user-info="slotProps">
{{ slotProps.user.age }}
</template>
</user-info>
獨(dú)占默認(rèn)插槽
當(dāng)被提供的內(nèi)容只有默認(rèn)插槽時(shí), 還有著下面的寫法:
// userInfo
<span>
<slot v-bind:user="user"></slot>
</span>
// parentComponent
<user-info v-slot="slotProps">
<template v-slot:default="slotProps">
{{ slotProps.user.age }}
</template>
</user-info>
或者, 將組件的標(biāo)簽當(dāng)做插槽的模板, 也就是把 <user-info> 當(dāng)做 <template> 標(biāo)簽來使用。這樣就可以把 v-slot 直接卸載組件的標(biāo)簽上:
// parentComponent
<user-info v-slot:default="slotProps">
{{ slotProps.user.age }}
</user-info>
或者:
// parentComponent
<user-info v-slot="slotProps">
{{ slotProps.user.age }}
</user-info>
注意:默認(rèn)插槽的縮寫語法不能和具名插槽混用, 否則會導(dǎo)致作用域不明確:
// parentComponent
<!--無效,會導(dǎo)致警告-->
<user-info v-slot="slotProps">
{{ slotProps.user.age }}
<template v-slot:other="otherSlotProps">
slotProps is NOT available here
</template>
</user-info>
只要是出現(xiàn)多個(gè)插槽的,必須為所有插槽使用完整的基于 <template> 的語法:
// parentComponent
<user-info>
<template v-slot:default="slotProps">
{{ slotProps.user.age }}
</template>
<template v-slot:other="otherSlotProps">
...
</template>
</user-info>