update: 2021/1
v-slot
指令版本
1. 普通插槽
- 父组件:
<template>
<base-layout>
abc
</base-layout>
</template>
- 子组件
BaseLayout.vue
:
<template>
<div>
<slot></slot>
</div>
</template>
运行结果:
2. 具名插槽
父组件:使用<template v-slot:**>
绑定插槽。
子组件:使用<slot name="**">
接收插槽传递的内容。
- 父组件:
<template>
<base-layout>
<template v-slot:title>
title
</template>
<template v-slot:content>
content
</template>
</base-layout>
</template>
- 子组件:
<template>
<div>
<h2 class="title">
<slot name="title"></slot>
</h2>
<div class="content">
<slot name="content"></slot>
</div>
</div>
</template>
注意
v-slot
只能添加在<template>
上 (只有一种例外情况),这一点和已经废弃的slot
attribute 不同。
运行结果:
3. 作用域插槽
简单来说,作用域插槽是让父组件可以访问子组件插槽里的值的方式。
3.1 独占默认插槽的缩写语法方式:
- 父组件:
<template>
<base-layout>
<template v-slot="slotProps">
{{slotProps.user.age}}
</template>
</base-layout>
</template>
- 子组件:
<template>
<div>
<slot v-bind:user="user">
{{user.name}}
</slot>
</div>
</template>
<script>
export default {
data () {
return {
user: {
name: 'abc',
age: 18
}
}
}
}
</script>
若父组件插槽不写,则默认显示子组件的user.name
的值。
运行结果:
3.2 多个作用域插槽的写法:
- 父组件:
<template>
<base-layout>
<template v-slot:default="slotProps">
{{slotProps.user.age}}
</template>
<template v-slot:other="otherSlotProps">
{{otherSlotProps.city.loc}}
</template>
<template v-slot:other2="otherSlotProps2">
{{otherSlotProps2.sport.time}}
</template>
</base-layout>
</template>
- 子组件:
<template>
<div>
<slot name="default" v-bind:user="user">
{{user.name}}
</slot>
<slot name="other" :city="city"></slot>
<slot name="other2" :sport="sport"></slot>
</div>
</template>
<script>
export default {
data () {
return {
user: {
name: 'abc',
age: 18
},
city: {
name: 'shandong',
loc: 'east'
},
sport: {
name: 'tennis',
time: 'eleven'
}
}
}
}
</script>
注意默认插槽的缩写语法不能和具名插槽混用,因为它会导致作用域不明确
运行结果:
3.3 多组件插槽嵌套的写法
- 父组件:
<template>
<base-info-template>
<template v-slot:title="slotProps" >
业务父组件页面 {{slotProps.titleData}}
</template>
<base-info-template>
</template>
- 子组件
BaseLayout.vue
:
<template>
<base-layout>
<template v-slot:middleware="{user}">
<span style="color: pink;">{{user.age}}</span>
<slot name="title" :titleData="titleData"></slot>
</template>
</base-layout>
</template>
<script>
import BaseLayout from './BaseLayout'
export default {
data () {
return {
titleData: '**默认标题**'
}
}
}
</script>
- 子组件
BaseInfoTemplate.vue
再引用子组件``BaseLayout.vue`:
<template>
<div>
<slot name="middleware" :user="user">
{{user.name}}
</slot>
</div>
</template>
<script>
export default {
data () {
return {
user: {
name: 'abc',
age: 18
}
}
}
}
</script>
运行结果:
解构插槽 Prop:官方文档
这个算是个语法糖~
eg.(同3.3的父组件代码)
<template>
<base-info-template>
<template v-slot:title="{titleData}" >
业务父组件页面{{titleData}}
</template>
</base-info-template>
</template>
具名插槽的缩写:官方文档
eg.(同3.3的父组件代码)
<template>
<base-info-template>
<template #title="slotProps" >
业务父组件页面 {{slotProps.titleData}}
</template>
</base-info-template>
</template>