父子孙slot插槽,如何高效接收与发送消息?

714 阅读4分钟

前言

  • 常网IT源码上线啦!
  • 本篇录入吊打面试官专栏,希望能祝君拿下Offer一臂之力,各位看官感兴趣可移步🚶。
  • 有人说面试造火箭,进去拧螺丝;其实个人觉得问的问题是项目中涉及的点 || 热门的技术栈都是很好的面试体验,不要是旁门左道冷门的知识,实际上并不会用到的。
  • 接下来想分享一些自己在项目中遇到的技术选型以及问题场景。

我们都渴望去理想世界,如丽江、大理。
但当理想世界一直给你在那生活,我们却不再以喜欢了。

1.jpg

自己的狗粮,自己赚。

一、前言

今天像往常一样,开开心心的打代码编程。

突然实习生小美问道:插槽父子孙,怎么接收消息和发送消息呀,giegie。

没办法,谁让她喊我哥哥呢。

于是便有了今天这篇文章,一起来探讨一下。

当然,你也可以当做面试题。

二、分析

我们封装一个组件A,一般情况下,其组件会有子组件B。即:A->B

而现在需要Q组件想来引用组件A,此时想要引用的时候,使用组件B的插槽,并且传递数据以及接收B组件的数据。

Q组件

<A>
  <template v-slot:cardTitle="item">
    <img @click.stop="collection(item.item)" />
  </template>
</A>

A组件

<B>
  <template v-slot:cardTitle="item">
    <slot name="cardTitle" :item="item.item"></slot>
  </template>
</B>

B组件

<slot name="cardTitle" :item="item"></slot>

我们定义了一个具体插槽slot,名字name为cardTitle,并且将item传递给父组件A。

而A组件,v-slot:cardTitle="item",cardTitle是接收他的子组件B的插槽,里面的item是子组件传递的数据。

我们看到A组件的template,包裹着slot插槽,这里的插槽,是接收父组件Q的结构,同样定义了name名字为cardTitle,并且将item传递出去。

来到Q组件,同样使用v-slot:cardTitle="item",来是收取子组件A的item数据。

其实,关键就是A组件作为中间者,怎么去把Q的传给B,又或者怎么把B传给Q。

小美心满意足的拿着答案离开了。

三、事件怎么传?

相信每个打工人,最放松的时刻是午休时间。

是吧。

结果午休期间,小美来一句:父组件给插槽传事件,插槽怎么接收事件?

我。。。

保证最后一个问题,我看着她诚恳的眼神,行吧。

父组件和子组件之间通过插槽来共享结构和内容,但插槽本身并不直接支持事件传递。不过,我们可以结合插槽和自定义事件,间接实现事件的传递。

父组件

通过slotProp.onClick,去调用插槽的onClick事件

<template v-slot:group="slotProp">
 <span @click="slotProp.onClick(slotProp.group)"> {{slotProp.group}} <span>	
</template>

子组件

可以自定义绑定事件on-click

<slot v-if="slotGroup" name="group" :group="group" 
	:on-click="groupRightClick(group)">
</slot>

解释:

  • 父组件:通过 <template v-slot:group="slotProps"> 插槽语法传递一个包含事件处理函数 onClick 的模板给子组件。slotProps 是一个插槽作用域对象,允许父组件访问子组件传递的事件。

  • 子组件:使用 <slot :on-click="groupRightClick(group)"> 语法,将自己的事件处理函数 onClick 传递给父组件,这样父组件就可以通过插槽触发这个事件。

但是如果你写:on-click="groupRightClick(group)"有个括号,就是执行意思;

事件处理函数会在父组件渲染的过程中立即触发。这是因为当子组件作为父组件的插槽内容时,插槽的内容会在父组件渲染时同步渲染并执行。

我们如果不要第一次就执行,则去掉括号。

子组件通过插槽触发事件并传递数据

父组件

<ChildComponent> 
    <template #default="slotProps">
        <button @click="slotProps.triggerEvent('Data from Parent')">Send Data</button> 
    </template> 
</ChildComponent>

子组件

<slot :triggerEvent="triggerEvent"></slot>

triggerEvent(data) { this.$emit('custom-event', data); }
  • 子组件:子组件提供了一个方法 triggerEvent,通过 slot 将这个方法暴露给父组件。父组件点击按钮时会触发这个方法。
  • 父组件:父组件通过插槽传递的 slotProps.triggerEvent 调用子组件的方法,并通过 @custom-event 监听从子组件发出的事件。

至此撒花~

后记

我们在实际项目中或多或少遇到一些奇奇怪怪的问题。

自己也会对一些写法的思考,为什么不行🤔,又为什么行了?

最后,祝君能拿下满意的offer。

我是Dignity_呱,来交个朋友呀,有朋自远方来,不亦乐乎呀!深夜末班车

👍 如果对您有帮助,您的点赞是我前进的润滑剂。

以往推荐

小小导出,我大前端足矣!

靓仔,说一下keep-alive缓存组件后怎么更新及原理?

面试官问我watch和computed的区别以及选择?

面试官问我new Vue阶段做了什么?

前端仔,快把dist部署到Nginx上

多图详解,一次性啃懂原型链(上万字)

Vue-Cli3搭建组件库

Vue实现动态路由(和面试官吹项目亮点)

项目中你不知道的Axios骚操作(手写核心原理、兼容性)

VuePress搭建项目组件文档

原文链接

juejin.cn/spost/74434…