Vue的插槽slot,分为3种
- 匿名插槽
- 具名插槽
- 作用域插槽
作用域插槽的慨念,文档却只有一句描述
有的时候你希望提供的组件带有一个可从子组件获取数据的可复用的插槽。
下面是2个父子的vue组件,先解释一下2个组件做了什么事情
- 父组件仅仅是调用了子组件
- 子组件内部实现了一个todolist列表
我建议从数据流动的角度,理解插槽作用域的使用方式,
- 1.父组件传递了todos数组给子组件
- 2.子组件通过props接受了数组数据,这里应该没有任何问题
- 3.子组件拿到数组后v-for渲染列表,并且通过 <slot :todo="todo">的方式,把数组内的每一个todo对象,传递给父组件
- 4.父组件通过slot-scope="slotProps"的方式,接受todo对象,之后就可以通过slotProps.todo.xxx的方式来使用了
所以数据的流动经历了
- 父组件传递todos数组给子组件
- 子组件遍历todos数组,把里面的todo对象传递给父组件
全部代码:
父组件的源码,也就是调用者
<template>
<todo-list :todos="todos">
<template slot-scope="slotProps">
<span v-if="slotProps.todo.isComplete">✓</span>
<span>{{slotProps.todo.text}}</span>
</template>
</todo-list>
</template>
<script>
import todoList from './todoList'
export default {
data () {
return {
todos: [
{
id: 0,
text: 'ziwei0',
isComplete: false
},
{
text: 'ziwei1',
id: 1,
isComplete: true
},
{
text: 'ziwei2',
id: 2,
isComplete: false
},
{
text: 'ziwei3',
id: 3,
isComplete: false
}
]
}
},
components: {
todoList
},
}
</script>
子组件源码,也就是封装组件的人
<template>
<ul>
<li v-for="todo in todos" :key="todo.id">
<slot :todo="todo">
</slot>
</li>
</ul>
</template>
<script>
export default {
props: {
todos: {
type: Array
}
}
}
</script>
并不是传回子组件。因为数据最初就不是在子组件的,是父组件的数据最终传回到父组件..
你的数据最初是在你的父组件里,这个场景下的子组件一般是类似element-ui那种的框架组件。
改变isComplete的值一般放到在父组件里改变。element-ui一般不会负责修改你的业务数据的,它只是负责帮你渲染,在合适的时机,比如点击todo时,把该项数据返回给你,让你这个组件的调用者去修改数据。