前言
插槽是Vue中一个重要的特性,它有很多种用法:默认插槽、具名插槽、作用域插槽。尤其作用域插槽,还有一堆特性,比如解构prop,解构prop的时候还可以进行属性名的映射。
记不住,根本记不住。
死记硬背当然记不住,但只要了解了原理,这些根本不用记。
为什么需要插槽
在深入原理之前,我们还是巩固一下基础。
为什么我们需要插槽这个特性,插槽到底是什么?
如果你看的是Vue2的文档,那么你会一头雾水:
Vue2几乎是没什么铺垫,上来就给你介绍插槽的特性。所以插槽到底是什么,为什么要用这个东西,得你自己悟。
Vue3的文档稍微好一点:
Vue3的文档说到了插槽的一些关键的点,但仍然很隐晦。
这里我们戳破这层窗户纸,给插槽一个明确的定义:
- 插槽给是组件的一种传参方式。组件可以通过props传参,也可以通过插槽传参。
- props传参传的是对象或值,插槽传的是模板内容
- 使用插槽的目的是将一部分由子组件负责的渲染工作交给父组件定义,提高的组件的灵活性
为什么要使用插槽呢?接下来我通过一个例子来说明。
现在假设你要实现一个无序列表的组件,基本长下面这样:
但是用户可能不满足于此,他们希望能让选项的字体加粗,或者变成斜体,或者改变字体颜色,或者在选项前面增加图标。更有甚者,他们希望选项的内容可以是更加复杂的DOM结构。
怎么办?如果没有插槽,你只能给组件提供足够多的props,让用户通过设置这些props来定制自己想要的效果。用户有新的需求,你也要跟着修改。
用插槽就可以完美解决这个问题。
我们定义一个组件List:
<script setup>
let props = defineProps(['data'])
</script>
<template>
<ul>
<li v-for="item in props.data">
<slot v-bind="item">{
{item.text}}</slot>
</li>
</ul>
</template>
父组件可以这么用:
<script setup>
import {
ref } from 'vue'
import List from './List.vue';
const data = [ {
text: 'Java' }, {
text: 'PHP'}, {
text: 'CSS'} ]
</script>
<template