在 2.6.0 中,我们为具名插槽和作用域插槽引入了一个新的统一的语法 (即 v-slot 指令)。它取代了 slot 和 slot-scope 这两个目前已被废弃但未被移除且仍在文档中的特性。新语法的由来可查阅 RFC。
引 vue 官方文档之前做项目时, 对插槽理解太少了, 这两天学习时, 才发现插槽更新用 v -slot 了, 自己做了些简单总结, 与大家分享一下~
插槽
我的理解就是父页面在组件标签内插入任意内容, 子组件内插糟 slot 控制摆放位置(匿名插槽, 具名插槽)
插槽分类
插槽一共就三大类 1. 匿名插槽(也叫默认插槽): 没有命名, 有且只有一个 2. 具名插槽: 相对匿名插槽组件 slot 标签带 name 命名的 3. 作用域插槽: 子组件内数据可以被父页面拿到(解决了数据只能从父页面传递给子组件)
匿名插槽(也叫默认插槽 default)
用法: 我的理解, 匿名插糟只需要一个.(就是这些, 不太复杂)父页面:
<todo-list>
<template v-slot:default>
任意内容
<p> 我是匿名插槽 </p>
</template>
</todo-list>
//v-slot:default 写上感觉和具名写法比较统一, 容易理解, 也可以不用写
子组件 todoList.vue
<slot> 我是默认值 </slot>
## 显示 ##
// 任意内容
// 我是匿名插槽
具名插槽(name)
用法: 我的理解, 和匿名插槽比较, 就是必须起名 todo 对应, 可以有多个具名插槽.(没了~)父页面
<todo-list>
<template v-slot:todo>
任意内容
<p> 我是匿名插槽 </p>
</template>
</todo-list>
// todo
data() {
return {
dynamicSlotName:”todo”
}
},
子组件
<slot name=”todo”> 我是默认值 </slot>
## 显示 ##
// 任意内容
// 我是匿名插槽
对 v-slot:todo 做操作:
动态命名
v-slot:{dynamicSlotName}// 替换标签上 v-slot:todo
具名插槽缩写(匿名插槽用法)(可以后看)
#todo 替换标签上 v-slot:todo
匿名如果想用必须加上 default
#default 替换标签上 v-slot:todo
父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。
作用域插槽
1. 重点是 slotProps 接取子组件里:user=”user” :test=”test” 类似属性的数据父页面
<todo-list>
<template v-slot:todo=”slotProps” >
{{slotProps.user.firstName}}
</template>
</todo-list>
//slotProps 可以随意命名
//slotProps 接取的是子组件标签 slot 上属性数据的集合所有 v -bind:user=”user”
子组件
<slot name=”todo” :user=”user” :test=”test”>
{{user.lastName}}
</slot>
data() {
return {
user:{
lastName:”Zhang”,
firstName:”yue”
},
test:[1,2,3,4]
}
},
// {{user.lastName}}是默认数据 v-slot:todo 当父页面没有(=”slotProps”)
// 时显示 Zhang
## 显示 ##
// yue
解构插槽 Prop
父页面 (子组件不变 显示一样)
// 相当于
function (slotProps) {
// 插槽内容
}
(slotProps)=> 参数可以用 slot 标签上现有的值 ({user,test}) 替换
<todo-list>
<template v-slot:todo=”{user,test}
” >
{{user.firstName}}
</template>
</todo-list>
## 显示 ##
## // yue
参数值替换名字(可以后看)
<todo-list>
<template v-slot:todo=”{user:person,test}
” >
{{person.firstName}}
</template>
</todo-list>
// v-slot:[dynamicSlotName]=”{user:person,test}
## 显示 ##
## // yue
独占默认插槽缩写 (可以后看) 感觉没什么机会用, 限制条件太多
总结
在用上 v -slot 之后 只需要考虑好 1. 是否需要命名(匿名插槽, 具名插槽)2. 父页面是否需要取存在子页面的数据(作用域插槽)
todo-list 实例
可以试一下, 便于理解~ 父页面
<template>
<div>
新插槽 v-slot 代替具名插槽 作用于插槽
<todo-list
>
<template #todo=”{todos:list}”>
<div @click = type(todos.id)>
{{list.text}}
</div>
</template>
</todo-list>
</div >
</template>
<script>
import todoList from “@/components/component/slotTodoChildren”;
export default {
name:”vSlot”,
components:{
todoList
},
data() {
return {
}
},
methods: {
type(data){
console.log(data)
}
},
}
</script>
子组件
<template>
<ul class=”slotTodoChildren”>
<li class=”lis”
v-for=”todo in todoList”
v-bind:key=”todo.id”
>
<!–
我们为每个 todo 准备了一个插槽,
将 `todo(todoList 里的)` 对象作为一个插槽的 prop 传入。
–>
<slot name=”todo” :todos=”todo”>
<!– 后备内容 –>
{{todo.text}}
</slot>
</li>
</ul>
</template>
<script>
export default {
name:”slotChildren”,
data() {
return {
todoList:[
{
id:1,
text:” 扫地 ”
},
{
id:2,
text:” 做饭 ”
},
{
id:3,
text:” 擦桌子 ”
}
]
}
},
created(){
console.log(this.filteredTodos)
}
}
</script>
<style scoped>
.slotTodoChildren .lis{
display: block;
background: #434534;
line-height:40px;
margin-top: 10px;
color: #fff;
font-size: 24px;
height: 40px;
}
</style>