slot插槽
slot简介
当我们使用子组件中的内容需要父组件来给予时,我们可以通过prop来传递。而有时,我们需要父组件给子组件传递一个标签,这时prop就会有些束手无策。这是就可以使用slot(插槽来解决)。我们可以简单的理解为,子组件中留出了一块空间让父组件放入父组件想要的标签或者是组件。
slot的使用
- 实例
子组件代码
<template>
<div>
<h2>这里是拥有插槽的子组件</h2>
<slot></slot>
</div>
</template>
<script>
export default {
name: "SlotDemo",
data() {
return {
user:{ firstName: "谷小桐", lastName: "ming" },
order:{
lastName: "li",
firstName: "ming",
},
};
},
};
</script>
我们在子组件中通过slot标签留出接口给父组件。而父组件可以通过这个接口展示任何想要展示的标签或组件。但是需要注意的是,我们不能在子组件对slot中接收的父组件的标签进行任何设置以及访问。简单理解为,子组件没有权限。
父组件代码
<template>
<div id="app">
<h3>这里是测试组件</h3>
<SlotDemo>
<h3>这里是父组件通过slot插槽传递给子组件的标签,子组件只能展示它,不能做修改</h3>
</SlotDemo>
</div>
</template>
上面的例子就是一个最基本的slot插槽的使用。
具名插槽
如果子组件只有一个插槽,那么父组件所传递的所有标签都会在slot中展示,而有时我们会在开发组件时根据情况设置多个插槽供父组件渲染,那么这是问题就来了,我们改如何区分每个插槽?父组件又如何准确地选择插槽进行渲染?
根据上一段的阐述,vue官方给出了具名插槽。显而易见,就是给每一个插槽命名。
我们通过slot标签的name属性给每个插槽命名。
子组件代码
<slot name='other'></slot>
<slot name='orderby'></slot>
如上,我们给每个插槽都命名了,而父组件想要确定选择那个插槽进行渲染,只需要在组件内使用template标签,通过template的v-slot语句来选择具名插槽。
父组件代码
<template>
<div id="app">
<h3>这里是测试组件</h3>
<SlotDemo>
<template v-slot:other> </template>
<template v-slot:orderby></template>
</SlotDemo>
</div>
</template>
以上代码为了演示,我并没有在插槽中给予内容。
作用域插槽
作用域最大的作用就是让插槽内容能够访问子组件中才有的数据。这是很有用的,我们不能确定父组件一定会使用插槽。但是又不希望插槽的位置空下来。这就要用到作用域插槽。我们给插槽默认值,并把想要让插槽访问的数据传递给插槽。
子组件代码
<template>
<div>
<h2>这里是拥有插槽的子组件</h2>
<slot name='other' :user='user'>{{user.lastName}}</slot>
<slot name='orderby' :order='order'>{{ order.lastName }}</slot>
</div>
</template>
<script>
export default {
name: "SlotDemo",
data() {
return {
user:{ firstName: "谷小桐", lastName: "ming" },
order:{
lastName: "li",
firstName: "ming",
},
};
},
};
</script>
在上面的子组件中,我们使用了作用域插槽,并且将数据user对象传递给了插槽,也将user对象的lastName属性作为插槽的默认值。
父组件代码
<div id="app">
<h3>这里是测试组件</h3>
<!-- <User :age='age'/> -->
<SlotDemo>
<template v-slot:other='fatherOther'> {{fatherOther.user.firstName}} </template>
<template v-slot:orderby='fatherorder'>{{fatherorder.order.firstName}}</template>
</SlotDemo>
</div>
- v-slot:后面跟着的是插槽的name属性,而=后面的fatherOther是我们在父组件中自己定义的名称用于接收子组件插槽传递的prop
- 在上面的例子中,我们在父组件接收了插槽的数据,并将插槽的默认值进行修改成了user对象的firstName。
- 需要注意的是例子中的fatherOther对象接收了插槽中所有传递的数据。我们在子组件中只传递了user对象,当我们在子组件传递多个时,都用fatherOther进行接收。
- 当我们在子组件中传递了多个数据给插槽,而又不使用全部,仅仅使用其中的一部分数据时,全部接收就显得有些不合理。这时,我们可以用到解构插槽 Prop
- 结构插槽用法代码
<SlotDemo >
<template v-slot='{order}'>{{order.firstName}} </template>
</SlotDemo >
- 要注意的是,我们在这里使用结构插槽时,父组件内的firstName并没有替换掉子组件的lastName
虽然我们在父组件中输出了firstName的属性值ming,但是子组件中的默认值lastName的属性值li依旧存在。
谷小桐的个人理解:作用域插槽的功能就是,我们将子组件中的data数据当做prop传递给了具名插槽,而所有使用该具名插槽的组件都可以接收该prop并在插槽内使用。不仅仅可以用来展示。而解构赋值就是我们选择性的就收具名插槽中prop的一部分,不接收全部的prop。