slot 插槽
插槽
vue 2.6后,插槽变动了,推荐使用最新版写法。
创建一个插槽
<slot></slot> //默认插槽
<slot name="demo"></slot> //具名插槽
使用插槽
假设插槽的组件标签为:ddd
<ddd>
<span>我会被插入默认插槽</span>
<template v-slot:demo>
<span>我会被插入demo插槽</span>
</template>
</ddd>
2.6的插槽,他必须是一个template元素包裹,template上使用v-slot指明插槽名。
简写
v-slot写起来很繁琐,当然会有简写形式
<ddd>
<span>我会被插入默认插槽</span>
<template #demo>
<span>我会被插入demo插槽</span>
</template>
</ddd>
后面跟着插槽名即可,极度方便,用了就回不来了。
作用域
ddd组件里面的slot,它与组件本身数据是不在同一个作用域的,因为slot内容,是通过另一个组件或者页面,在调用ddd时,插入的,而插入的内容,是无法直接访问ddd组件的数据的。
如:
ddd组件
<template>
<div>
<slot></slot>
</div>
</template>
<script>
export default {
data(){
return {
title:"我是子组件"
}
}
}
</script>
调用ddd组件的页面或组件
<template>
<ddd>
<span>{{title}}</span>
</dddd>
</template>
<script>
import ddd from "./ddd";
export default {
data(){
return {
title:"我是父组件"
}
},
components:{
ddd
}
}
</script>
渲染出来后:
<div>
<span>我是父组件</span>
</div>
插槽无法直接获取到插槽所在子组件内的数据。
作用域插槽(插槽获取子组件中才有的数据)
简单点来说,就是ddd里面的插槽获取ddd里面的数据
ddd组件
<template>
<div>
<slot :title="title"></slot>
</div>
</template>
<script>
export default {
data(){
return {
title:"我是子组件"
}
}
}
</script>
调用ddd组件的页面或组件
<template>
<ddd v-slot:default="title">
<span>{{title}}</span>
</dddd>
</template>
<script>
import ddd from "./ddd";
export default {
data(){
return {
title:"我是父组件"
}
},
components:{
ddd
}
}
</script>
渲染出来后:
<div>
<span>{title:"我是子组件"}</span>
</div>
你会发现v-slot:default="title"
的这个title并不是指的ddd里面:title="title"
title本身,他就好像是一个键值对的key一样。
而这个key所对应的值,也不是title这个具体的数据,他实际上是保存着所有ddd组件绑定的值。
所以,这个key其实是可以自定义名字的,不一定非要叫title
<template>
<ddd v-slot:default="slotProps">
<span>{{slotProps.title}}</span>
</dddd>
</template>
<div>
<span>我是子组件</span>
</div>
传递多个数据
<template>
<div>
<slot :title="title" test="测试数据" aaa="我是aaa"></slot>
</div>
</template>
<template>
<ddd v-slot:default="slotProps">
<span>{{slotProps.title}}</span>
<span>{{slotProps.test}}</span>
<span>{{slotProps.aaa}}</span>
</dddd>
</template>
<div>
<span>我是子组件</span>
<span>测试数据</span>
<span>我是aaa</span>
</div>
缩写
v-slot:default="slotProps"
指明这是一个默认的插槽,对于默认插槽,其实我们可以省略不写default的。
<template>
<ddd v-slot="slotProps">
<span>{{slotProps.title}}</span>
<span>{{slotProps.test}}</span>
<span>{{slotProps.aaa}}</span>
</dddd>
</template>
但是,如果有多个插槽,比如默认插槽和具名插槽都同时存在,不管具名的插槽有没有传值,都不能使用这样的缩写,因为会导致作用域不明确。
<template>
<ddd>
<!--默认插槽-->
<template v-slot:default="slotProps">
<span>{{slotProps.title}}</span>
<span>{{slotProps.test}}</span>
<span>{{slotProps.aaa}}</span>
</template>
<!--具名插槽-->
<template v-slot:other="otherSlotProps">
<span>{{otherSlotProps.title}}</span>
</template>
</dddd>
</template>
只要出现多个插槽,请始终为所有的插槽使用完整的基于 <template>
的语法
解构插槽prop
既然插槽传过来的是一个数据的集合,是一个键值对的对象,那么我们也是可以使用解构来快速获取数据的。
<template>
<ddd v-slot="{title,test,aaa}">
<span>{{title}}</span>
<span>{{test}}</span>
<span>{{aaa}}</span>
</dddd>
</template>
动态插槽名
动态指令参数也可以用在 v-slot
上,来定义动态的插槽名:
<base-layout>
<template v-slot:[dynamicSlotName]>
...
</template>
</base-layout>
插槽缩写补充
之前我们说了,v-slot
可以用#
缩写符号代替,那么有prop传参的情况下怎么写?
<ddd>
<template #default="{title}">
<span>{{title}}</span>
</template>
<template #demo="{title}">
<span>{{title}}</span>
</template>
</ddd>
使用了#
符号来缩写,默认插槽default就必须写上名字,不能直接#={title}
,这样是会报错的。
以上就是对于新版插槽的理解。
本文系作者 @木灵鱼儿 原创发布在木灵鱼儿站点。未经许可,禁止转载。
暂无评论数据