继具名插槽后,深入学习了作用域插槽。
由于渲染作用域的限制,父组件中的插槽内容无法访问到子组件内的状态。但是有时候渲染的内容还真就需要父组件和子组件双方的数据共同组成,这时候就用到了作用域插槽。
补充:插槽内容是一个固定搭配,是指代组件中的内容(可以是文本,也可以是组件)。如果还有疑问请看如下示例。(我自己描述的也不是很清楚,但是例子一看就明白了)
1、<SubmitButton>Save</SubmitButton>
2、<FancyButton>
<span style="color:red">Click me!</span>
<AwesomeIcon name="plus" />
</FancyButton>
其中,文本Save,还有span标签和<AwesomeIcon />子组件这些都叫做插槽内容,因为本来组件内是无法有内容的,但是因为插槽的出现,让我们自己定义的组件内可以放内容,这也就是其他文章里说的---可扩展性。
那好,我们继续8。
我们有了解决的办法,要理解这个办法,可以类比于父子通信的Props(子组件自己定义需要接受的props,然后由父组件传给子组件)。那么好,回到我们的话题,本来子组件由于插槽的存在,是可以接受父组件那边传来的数据的,现在我们需要的是让子组件给父组件的插槽内容提供数据,相当于发货商和收货商反过来了。
接着这个思路,我们就要在子组件内的<slot>中也像定义Prop那样,定义要传给父组件插槽内容的数据(哈哈没错,之前prop是一个组件需要接受的数据,而这个是要抛出的数据)。
注意!!!默认插槽和具名插槽在使用上还是有一点点区别的,下面将分开讲:
默认插槽---作用域插槽
上面我们说到,要传给父组件数据,需要在子组件上的slot标签内添加要抛出的数据,请看下图:
---子组件<MyComponent/>内---
<div>
<slot text="hello" count="1"></slot>
</div>
这样就定义好了需要向父组件传输的数据了(一个文本和一个数字)
那么父组件该怎么接受这两个数据呢?
---父组件内---
<MyComponent v-slot="slotProps">
{{ slotProps.text }} {{ slotProps.count }}
</MyComponent>
这样就接收到了~
我们会发现,多了一个v-slot指令,没错,我们需要这个指令帮助我们接受到子组件内传来的数据。而接收到的数据将会以对象的形式存到slotProps这个变量里,所以此时slotProps = { text:“hello”,count:1},然后我们就可以在插槽内容中使用热乎的子组件内数据啦。此外,也同样支持解构写法。
<MyComponent v-slot="{ text, count }">
{{ text }} {{ count }}
</MyComponent>
哦对了,如果想动态绑定我们所抛出的数据的话,就可以用v-bind(:)+key(text)= ‘子组件内的状态’---( <slot : text="状态a" : count="状态b"></slot> )
具名插槽---作用域插槽
和默认插槽的区别就是他多了一个名字。
---子组件---
<slot name="header" message="hello"></slot>
现在我们应该可以看懂了,message是要抛出的数据,而name是要传给哪一个插槽内容的定向标志(可以说是)
---父组件---
<MyComponent>
<template #header="header">
{{ header }}
</template>
<template #default="default">
{{ default }}
</template>
<template #footer="footer">
{{ footer }}
</template>
</MyComponent>
在具名插槽中父组件接受子组件的数据,也用到了v-slot指令,不过由于v-slot : name = "dataObj"可以简写,就写成了#name = ”dataObj”。
由于有了name,所以我们的数据就可以定向传输了(或说是私有化了),#header对接name=”header“,所以子组件传的数据被header接受了(header是一个对象{ message: 'hello'
},同样也可以解构),只能在<template #header = "header"></template>内访问使用。
补充:默认插槽其实也有name,只不过我们不显式的写出来,他的name = "default"。
当我们默认插槽和具名插槽混用时,我们需要显式的写出默认插槽的name。
<MyComponent>
<!-- 使用显式的默认插槽 -->
<template #default="{ message }">
{{ message }}
</template>
<template #footer>
阿巴阿巴阿巴...
</template>
</MyComponent>
为默认插槽使用显式的 <template>
标签有助于更清晰地指出 message
属性在其它插槽中不可用
使用场景实例
官方文档中有一个高级列表组件示例可以看看:https://cn.vuejs.org/guide/components/slots.html#scoped-slots
这是我第一个博客,嗯...让我想一个口号吧......
为了更美好的明天而战(哈哈很中二)