簡介
插槽:簡單理解就是組件內(nèi)部留一個或多個的插槽位置,可供組件傳對應的模板代碼進去。插槽的出現(xiàn)动羽,讓組件變的更加靈活。
一渔期、匿名插槽
// 組件(父)
<my-component>
<p>hello,world!</p>
</my-component>
// 組件內(nèi)部(子)
<div class="child-page">
<h1>子頁面</h1>
<slot></slot> // 替換為 <p>hello,world!</p>
</div>
// 渲染結(jié)果
<div class="child-page">
<h1>子頁面</h1>
<p>hello,world!</p>
</div>
以上是最簡單的匿名插槽eg
二运吓、具名插槽
顧名思義就是帶名字的插槽,假如需要在組件內(nèi)部預留多個插槽位置疯趟,就需要為插槽定義名字拘哨,指定插入的位置。
// 組件(父)
<my-component>
<template v-slot:header>
<p>頭部</p>
</template>
<template v-slot:footer>
<p>腳部</p>
</template>
<p>身體</p>
</my-component>
// 組件內(nèi)部(子)
<div class="child-page">
<h1>子頁面</h1>
<slot name="header"></slot>
<slot></slot> // 等價于 <slot name="default"></slot>
<slot name="footer"></slot>
</div>
// 渲染結(jié)果
<div class="child-page">
<h1>子頁面</h1>
<p>頭部</p>
<p>身體</p>
<p>腳部</p>
</div>
vue >=2.6.0版本信峻,使用v-slot替代slot 和 slot-scope倦青。
注意三點
- 具名插槽的內(nèi)容必須使用模板<template></template>包裹
- 不指定名字的模板插入匿名插槽中,推薦使用具名插槽盹舞,方便代碼追蹤且直觀清楚
- 匿名插槽具有隱藏的名字"default"
三产镐、具名插槽的縮寫和動態(tài)插槽名
具名插槽縮寫
<my-component>
<template #header>
<p>頭部</p>
</template>
<template #footer>
<p>腳部</p>
</template>
<template #body>
<p>身體</p>
</template>
</my-component>
動態(tài)插槽名
<my-component>
<template #[headerPart]> // v-slot:[headerPart]
<p>頭部</p>
</template>
<template #footer>
<p>腳部</p>
</template>
<template #body>
<p>身體</p>
</template>
</my-component>
...
data() {
return {
headerPart: 'header'
}
}
四、插槽參數(shù)傳遞
父傳子
// 組件(父)
<my-component
:title="'我是'"
>
<template #header>
<p>頭部</p>
</template>
<template #footer>
<p>腳部</p>
</template>
<template #body>
<p>身體</p>
</template>
</my-component>
// 組件內(nèi)部(子)
<div class="child-page">
<h1>{{title}}子頁面</h1>
<slot name="header"></slot>
<slot name="body"></slot>
<slot name="footer"></slot>
</div>
props: {
title: {
type: String
}
}
以下這種傳參是錯誤的
<my-component
:title="'我是'"
>
<template #header>
<p>{{title}}頭部</p> // 錯誤
</template>
<template #footer>
<p>腳部</p>
</template>
<template #body>
<p>身體</p>
</template>
</my-component>
所以如果需要動態(tài)修改插槽的內(nèi)容,就需要子組件傳參給父組件贾虽。
子傳父
// 組件(父)傳參并接受參數(shù)
<my-component
v-bind="layout" // 傳遞參數(shù)
>
// 可以使用ES6解構(gòu){ slotProps }
<template #header="slotProps"> // 接受參數(shù)
<p>{{slotProps.headers}}</p>
</template>
<template #footer="slotProps">
<p>{{slotProps.footers}}</p>
</template>
<template #body="slotProps">
<p>{{slotProps.bodys}}</p>
</template>
</my-component>
...
data() {
return {
layout: {
header: '頭部',
body: '身體',
footer: '腳部'
}
}
}
// 組件內(nèi)部(子)
<div class="child-page">
<h1>子頁面</h1>
<slot name="header" :headers="header"></slot>
<slot name="body" :bodys="body"></slot>
<slot name="footer" :footers="footer"></slot>
</div>
...
props: {
header: {
require: true
},
body: {
require: true
},
footer: {
require: true
}
}
總結(jié):
父組件傳參給子組件逃糟,props接收后,插槽slot再通過綁定屬性傳遞參數(shù)返回給父組件蓬豁,不管是模板代碼還是數(shù)據(jù)绰咽,控制權(quán)完全掌握在父組件手里。