插槽<slot>主要实现分发,当父组件引用带有插槽的子组件时,引用处的子组件内如有内容,当组件渲染的时候,<slot></slot> 将会被替换
1、默认插槽的使用:
slot-one组件:
<template>
<view>
<view>我是子组件</view>
<slot></slot>
</view>
</template>
父组件引用slot-one组件:
<template>
<view class="slot-item">
<slot-one>
父组件插槽内容
</slot-one>
</view>
</template>
<script>
import slotOne from "./slot1.vue"
export default {
components: {
slotOne,
}
}
</script>
<style scoped>
.slot-item{
padding:50rpx;
}
</style>
效果:
2、插槽内可以包含任何模板代码,包括 HTML:
slot-one组件如上不变。
父组件引用slot-one组件:
<view class="slot-item">
<slot-one>
<text style="color:red">插槽内可以包含任何模板代码,包括 HTML</text>
</slot-one>
</view>
效果:
3、插槽内可以包含其它的组件,下面的内容来自slotTwo组件:
slot-one组件如上不变,slot-two组件:
<template>
<view class="slottwo">
<view>slottwo</view>
</view>
</template>
父组件引用slot-one组件,slot-one包含slot-two组件:
<view class="slot-item">
<slot-one>
<text style="color:red">插槽内可以包含其它的组件,下面的内容来自slotTwo组件</text>
<slot-two></slot-two>
</slot-one>
</view>
效果:
4、后备内容:
- 有时为一个插槽设置具体的后备 (也就是默认的) 内容是很有用的,它只会在没有提供内容的时候被渲染,
- 但是如果我们提供内容,则这个提供的内容将会被渲染从而取代后备内容
slot-one组件(带有默认值):
<template>
<view>
<view>我是子组件</view>
<slot>slot后备内容</slot>
</view>
</template>
父组件引用slot-one组件:
<view class="slot-item">
<slot-one>
</slot-one>
<slot-one>
<text style="color:red">提供的内容将会被渲染从而取代后备内容</text>
</slot-one>
</view>
效果:
5、具名插槽:
- 有时我们需要多个插槽,<slot> 元素有一个特殊的 attribute:name,语法: <slot name="**"></slot>,用来定义额外的插槽
- 一个不带 name 的 <slot> 出口会带有隐含的名字“default”
- 在向具名插槽提供内容的时候,我们可以在一个 <template> 元素上使用 v-slot 指令,并以 v-slot 的参数的形式提供其名称
- v-slot 也有缩写,即把参数之前的所有内容 (v-slot:) 替换为字符 #。例如 v-slot:header 可以被重写为 #header
- v-slot 只能添加在 <template> 上 ,绑定在其他元素上用slot="**"
slot-two组件:
<template>
<view class="slottwo">
<view>slottwo</view>
<slot name="header"></slot>
<slot></slot>
<slot name="footer"></slot>
</view>
</template>
父组件引用slot-two组件:
<view class="slot-item">
<slot-two>
<view>default:没有指定name的默认插槽的内容</view>
<template v-slot:header>
<text>header:我是name为header的slot</text>
</template>
<text slot="footer">footer:我是name为footer的slot</text>
</slot-two>
</view>
效果:
6、解构插槽 Prop:
- 绑定在 <slot> 元素上的 attribute 被称为插槽 prop。
- 在父级作用域中,我们可以使用带值的 v-slot 来定义我们提供的插槽 prop 的名字
slot-three组件:
<template>
<view>
我是作用域插槽的子组件
<slot :user="user" :city="city"></slot>
</view>
</template>
<script>
export default {
data() {
return {
user: [{name: 'Jack',sex: 'boy'},{name: 'Jone',sex: 'girl'},{name: 'Tom',sex: 'boy'}],
city: [{name: '北京'},{name: '上海'},{name: '广州'}]
};
}
}
</script>
父组件引用slot-three组件:
<view class="slot-item">
<slot-three>
<template v-slot="{user,city}">
<view v-for="(item, index) in user" :key="index">
{{item.name}}
</view>
<view v-for="(item, index) in city" :key="index">
{{item.name}}
</view>
</template>
</slot-three>
</view>
效果:
7、示例:
todoList组件:
<template>
<ul>
<li v-for="todoitem in todos" :key="todoitem.id">
<!-- 我们为每个 todoitem 准备了一个插槽, 将 `todoitem` 对象作为一个插槽的 prop 传入。 -->
<slot name="todo" :todoitem="todoitem">
<!-- 后备内容 -->
{{ todoitem.text }}
</slot>
</li>
</ul>
</template>
父组件引用todoList组件:
<view class="slot-item">
<todo-list :todos="todos">
<template v-slot:todo="{ todoitem }">
<span v-if="todoitem.isComplete">✓</span>
{{ todoitem.text }}
</template>
</todo-list>
</view>
data() {
return {
todos: [{
text: "aa",
id: "aa",
isComplete: true
}, {
text: "bb",
id: "bb",
isComplete: true
}, {
text: "cc",
id: "cc",
isComplete: false
}]
};
},
效果: