原文网址:Vue--插槽(v-slot)--使用/教程/实例_IT利刃出鞘的博客-CSDN博客
简介
说明
本文用示例说明Vue的插槽(v-slot)的用法。包括:普通插槽,作用域插槽等。
官网
普通插槽
说明
vue 在 2.6.0 中,具名插槽和作用域插槽引入了一个新的统一的语法 (即 v-slot 指令),它取代了 slot 和 slot-scope,这两个在vue2.6.x中已被废弃但未被移除。vue 3 中, slot 和 slot-scope会被直接移除。
具名插槽
父组件:<template v-slot:name1> //简写方式:<template #name1="data1">
子组件:对应:<slot name='name1'><slot>
无名插槽
父组件所有不带插槽名字的<template>或者不在<template>中的内容,都会被放到子组件默认插槽中:<slot></slot>。
实际上,这两种都会带有隐含的名字:default
slot与v-slot区别
项 | slot | v-slot |
用法 | 父组件:<template slot="test"><template> 子组件:<slot name=“test”></slot> | 父组件:<template v-slot:test><template> 子组件:<slot name=“test”></slot> |
使用位置 | 可用在任意标签,如:<p slot="test"><p> | 只能用在 组件component 或者 template 上 |
作用域插槽
具名作用域插槽写法
父组件:<template v-slot:name1="data1"> //简写方式:<template #name1="data1">
子组件:对应:<slot name='name1' :data2="childData"><slot>
prop名字问题
在使用时,父组件的取值的名字必须与子组件返回的相同,如下图加粗部分所示:
父组件:<template #test="data1"> {{data1.data2}} </template>
子组件:<slot name=“test” :data2=“testData”></slot>
说明:父组件的data1里边包含的就是这样的数据:{"data2": testData绑定的对象},所以通过data1已经可以获取到数据了。
默认作用域插槽写法
默认插槽 可以写成 v-slot='xxx'。也就是:<template v-slot:default="xxx">
注意:<template #="xxx"> 这样写是不对的,#之后必须带参数。
作用域解构插槽
父组件:<template v-slot="{data2}"> //这个名字(prop)必须对应下方加粗部分的名字
子组件:对应:<slot name='name1' :data2="childData"><slot>
说明:
- 可以对父组件prop重命名:<template v-slot="{data2 : person}">
- 可以设置默认内容:<template v-slot="{data2 : {name: "Tony"}}">
- 以上边为例,获取的data2是childData对应的对象。
支持动态插槽名
<template v-slot:[dynamicSlotName]>
slot与v-slot区别
项 | slot | v-slot |
用法 | 父组件:<template slot="test" slot-scope=“data1”> {{data1.data2}} </template> 子组件:<slot name=“test” :data2=“testData”></slot> | 父组件:<template #test="{data1}"> {{data1.data2}} </template> 子组件:<slot name=“test” :data2=“testData”></slot> |
使用位置 | 可用在任意标签,如:<p slot-scope:data="test"><p> | 只能用在 组件component 或者 template 上 |
实例1:子获取父的值
router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import ComponentA from "../components/ComponentA";
Vue.use(Router)
export default new Router({
routes: [
{
path: '/component-a',
name: 'ComponentA',
component: ComponentA
}
]
})
components/ComponentA.vue(父组件)
<template>
<div class="container-component-a">
<p>ComponentA</p><hr>
<component-b name1="abc">
<div>ComponentA的div</div>
</component-b>
</div>
</template>
<script>
import ComponentB from "./ComponentB";
export default {
components: {ComponentB},
}
</script>
<style scoped>
</style>
components/ComponentB.vue(子组件)
<template>
<div class="container-component-b">
<p>ComponentB</p>
<div>
<div>ComponentB的div</div>
<slot></slot>
</div>
</div>
</template>
<script>
export default {
}
</script>
<style scoped>
</style>
测试
访问:http://localhost:8080/#/component-a
实例2:父子相互取值
router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import ComponentA from "@/components/ComponentA";
Vue.use(Router)
export default new Router({
routes: [
{
path: '/componentA',
name: 'ComponentA',
component: ComponentA
}
]
})
components/ComponentA.vue(父组件)
<template>
<div class="container-component-a">
<p>ComponentA</p>
<hr>
<component-b>
<template v-slot:name1="data1">
{{ data1 }}
</template>
</component-b>
</div>
</template>
<script>
import ComponentB from "./ComponentB";
export default {
components: {ComponentB},
}
</script>
<style scoped>
</style>
components/ComponentB.vue(子组件)
<template>
<div class="container-component-b">
<p>ComponentB</p>
<slot name="name1" :data2="user"></slot>
</div>
</template>
<script>
export default {
data() {
return {
user: {
lastName: 'Stark'
}
}
}
}
</script>
<style scoped>
</style>
测试
访问:http://localhost:8080/#/component-a
实例3:todo列表
简介
本处在子组件中有要做的事情(包括已完成的和未完成的),然后父组件对其进行显示,如果已经完成,就在前边打个“√”。
router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import ComponentA from "../components/ComponentA";
Vue.use(Router)
export default new Router({
routes: [
{
path: '/component-a',
name: 'ComponentA',
component: ComponentA
}
]
})
components/ComponentA.vue(父组件)
<template>
<div class="container-component-a">
<p>ComponentA</p><hr>
<component-b>
<template v-slot:name1="data1">
<span v-if="data1.data2.isCompleted">√</span>
{{data1.data2.title}}
</template>
</component-b>
</div>
</template>
<script>
import ComponentB from "./ComponentB";
export default {
components: {ComponentB},
}
</script>
<style scoped>
</style>
components/ComponentB.vue(子组件)
<template>
<div class="container-component-b">
<p>ComponentB</p>
<ul>
<li v-for="todo in todoLists" v-bind:key="todo.id">
<slot name="name1" :data2="todo"></slot>
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
todoLists: [
{
id: 1,
title: 'Do the dishes',
isCompleted: true,
},
{
id: 2,
title: 'Take out the trash',
},
{
id: 3,
title: 'Wash the clothes'
}
]
}
}
}
</script>
<style scoped>
</style>
测试
访问:http://localhost:8080/#/component-a
其他网址
深入了解组件 - 插槽 - 《Vue.js v2.x 官方教程》 - 书栈网 · BookStack
Vue 2.6+ 你需要知道的 v-slot - 简书
vue---slot,slot-scoped,以及2.6版本之后插槽的用法 - 站住,别跑 - 博客园
vue作用域插槽,你真的懂了吗?
slot-scope:作用域插槽特性:子组件传递数据给父组件_灵灵7的博客-CSDN博客