我们再来学习一些插槽相关的高级语法,
示例代码:

【Vue】作用域插槽_插槽

代码解读:
我们通过代码的案例来学习插槽的简写,比如说你现在写了两个具名的插槽,‍‍你要写v-slot 冒号head,你可以把它简写成井号head这样的语法就可以了:

【Vue】作用域插槽_插槽_02

你会发现具名插槽 你可以通过这样的一个井号的语法对它做简写。‍‍

接着来学习作用域插槽,它是怎么一回事?
我来给大家举一个例子。首先我定一个子组件叫做list,在这里面我定一个数据 data,‍‍return一个list,它就是一个数组,123就可以了:

【Vue】作用域插槽_vue.js_03

我们定义了一个123这样的数组,‍‍然后我们在这里写一个div去对123做循环,怎么循环呢?‍‍
示例代码:

【Vue】作用域插槽_数据_04

V-for等于item in list。这里用item就行了,然后我上面组件‍‍就去调用下面的叫做list的组件:

【Vue】作用域插槽_数据_05


代码解读:

子组件调用一个子组件,子组件里面有一个数据做循环,但是假设有这样一个需求,‍‍我现在到底是通过div标签去做我子组件的循环 还是通过其他的标签做子组件的循环?

我可以由外部组件来决定,也就是说我不把它写死,我可以由外部传给我,想做到这个功能怎么做?

我们可以这么去写,‍‍我们可以通过一个作用域插槽来写。‍‍

首先我在这里告诉子组件你的循环该怎么去展示,
比如说我不用div了,我用一个span标签来展示我的子组件里面的每一项的内容,‍‍

我调子组件的时候,把 span 标签通过slot传给子组件。‍‍那么在子组件里面怎么去用传递过来的 内容 ?
代码示例:

【Vue】作用域插槽_javascript_06

代码解读:
在这里是不是就可以用slot的内容了。用了它之后我们需要怎么去做?‍‍
我们现在循环的就不是div标签了,循环的就是slot了,

接着循环slot的时候,slot不知道它要展示什么,‍‍如果你这么去写的话,它只会展示三个span标签,因为它不知道中间的内容应该展示什么。‍‍

刷新页面,‍‍不会报错,你点开页面上应该会有三个span标签:

【Vue】作用域插槽_javascript_07

因为你传递过来了一个slot,我这块把slot循环了三次,‍‍接着我要想把123循环的时候让slot做一个展示,可以怎么写?

ni可能会想直接在这写:

【Vue】作用域插槽_javascript_08

你不是循环吗?调用我上面传递过来这个span标签吗?‍‍我把item传递给你这个slot标签,slot标签是不是在这里直接能用这个item?

这样写没有任何的效果。‍‍
如果你在父组件里写 item 的内容,ta会到父组件里面去找 item 对应的值,‍‍但实际上你这个item是在子组件里的,所以你这么用是不行的,那想去用它该怎么办呢?‍‍

我们调用slot的时候需要通过属性的形式把对应的参数传给slot,‍‍我们把item通过一个叫做item这样的属性传给 slot:

【Vue】作用域插槽_前端_09

slot这块我就可以去接收,‍‍怎么接受?‍‍

【Vue】作用域插槽_前端_10

在这一块我们写内容的时候调list组件的时候,我就可以写一个v-slot等于‍‍slotProps,意思是什么?

你调我slot的时候把一些东西传给我了,‍‍所有传递给我的内容我都放到slotProps里面去接收。

那么在这里我直接可以通过slotProps点item‍‍获取到你调用我的时候传递给我的一些内容,通过span我可以展示它,‍‍我改成div,它应该变成三行。

我们写完了作用域插槽之后,‍‍我们再来回过来研究一下它的执行流程。‍‍
首先我父组件调用list 子组件,‍‍这块就是传递给子组件的一个slot:

【Vue】作用域插槽_vue.js_11

那么我在子组件里面去循环我内容的时候,‍‍我去调用这个slot,意思就是我要通过div这种形式去展示我的内容,‍‍但是我在调slot的时候,我把一些数据传给slot,把哪些数据传给slot?
把item这些数据传给slot,‍‍slot怎么接收它?‍‍
通过v杠slot等于slotProps这样的数据对象,‍‍
所有你传递过来的内容都在slotProps里面去接收,‍‍那么接收你传过来的内容之后,在这里我就可以用 item 传递过来的值了:

【Vue】作用域插槽_前端_12

父组件调子组件的时候传slot进来,‍‍子组件再通过属性的形式把数据传给父组件,父组件拿到内容之后再决定它怎么显示。

上面代码可以简写成:【叫解构】

【Vue】作用域插槽_插槽_13

因为你slotProps接收到的是你传给 slot所有的内容,‍‍我现在只用​​{item}​​​,你可以直接在这里去把item解构出来,‍‍你下面直接就可以用​​{{item}}​​。‍‍

我们回忆一下作用域插槽解决了什么问题,解决的就是‍‍当子组件渲染的内容要由父组件决定的时候,比如说你到底要怎么展示这个列表是由父组件决定的时候,‍‍我就可以通过这个作用域插槽来实现。

为什么要作用域插槽?因为通过插槽的写法‍‍能够让父组件去调用子组件里面的 item数据,以前我们在父组件里直接写 item 是不行的,‍‍因为它只能从父组件作用域里面去找 item 数据,所以找不到它就显示不了,‍‍通过这个作用域插槽能够把父组件的 item 数据从子组件传递过来,‍‍父组件里面理论上就可以调用子组件的数据了。‍‍

我们在写一些Vue组件/插件的时候,我们会用的比较多。