Vue面试之组件通信的方式总结(下篇)

Vue面试之组件通信的方式总结

  • $ref
  • provide&inject
    • provide
    • inject
  • EventBus事件总线
  • vuex

        最近在整理一些前端面试中经常被问到的问题,分为vue相关、react相关、js相关、react相关等等专题,可持续关注后续内容,会不断进行整理~

        在Vue框架中,提供了多种组件通信方式:props父子组件传参、插槽传参、Event Bus方式、vuex方式传参等,之前已对前两种方式进行了总结,本文继续总结其余方法~

$ref

在Vue中很少会直接操作DOM,但是一般情况下会用ref和$ refs取某DOM结构,具体来说:利用ref给元素或子组件注册信息,则该信息就会被注册到父组件的$ refs对象上。
$refs是一个对象,包含已经注册过ref的所有子组件的内容

ref有三种用法:

  1. ref加在普通元素上,则通过this.$refs.xxx获取到的是dom元素;
<p id="p1" ref="p1">这是第一段</p>
console.log(this.$refs.p1) // 就可以拿到p1对应的dom元素

ref用在普通元素上
2. ref加在子组件上,则通过this.$refs.xxx获取到的是组件,可拿到子组件的所有属性和方法,实现子组件向父组件通信;同时如果在使用子组件方法时传入参数,则可以实现父组件向子组件通信;

父组件可以拿到子组件上的所有属性和方法
上图展示了利用this.refs.xxx可以获取到子组件身上的所有属性和方法,从而实现子组件向父组件通信;
这里需要注意的一点是,$refs只有在子组件被渲染后才能拿到,使用时一定要确保子组件已经被渲染,否则拿到的只能是undefined
父组件利用子组件的submit方法,可在使用时传递参数,这样调用时,子组件就可以拿到传递过来的参数值,实现父组件向子组件的通信;

<!-- 父组件中 -->
<Son ref="son"></Son>
<button @click="finish">提交</button>
// 父组件中 
finish() {this.$refs.son.submit('12')// 调用子组件中的submit方法,并将12作为参数传递
}
// 子组件中 
submit(params) {console.log('拿到了父组件传递过来的参数', params)// 可以拿到父组件传递过来的参数12
}
  1. 如果使用 v-for 渲染多个相同类型的子组件,$refs 将成为一个数组。

provide&inject

provideinject也可以用来进行跨层级组件通信,父组件通过provide提供数据或方法,而子孙组件通过inject拿到数据或方法;

provide

它有两种写法:

  1. 对象写法
    如果传递的数据是个‘死数据’(静态数据),则可以直接利用对象形式将其传递;
// Parent.vue
export default {
// provide对象写法,直接将数据进行传递provide: {age: 13},
};
  1. 函数写法
// Parent.vue
export default {data() {return {list: [...], // 一些数据};},provide() {// provide函数写法,可以将动态数据传递return {list: this.list, // 提供属性submit: this.submit // 提供方法};},methods: {submit() {// 一些逻辑}}
};

inject

inject的写法也有两个:

  1. 数组写法
    如果不用给传递过来的数据重命名,可采用此方法(上例中的传递age)
// Child.vue
export default {inject: ['age'], // 数组形式mounted() {console.log(this.age); // 可以访问父组件提供的数据,12},
};
  1. 对象形式
    如果需要对传递过来的数据重命名,可采用对象形式(上例中传递submit与list)
// Child.vue
export default {inject: {parentList: 'list',parentSubmit: 'submit'},mounted() {console.log(this.parentList); // 可以访问父组件提供的数据this.parentSubmit(); // 可以调用父组件提供的方法},
};

需要注意的是,provide 提供的数据不是响应式的,这意味着如果提供的数据发生变化,子组件不会自动重新渲染。如果需要响应式数据,可以使用 Vue 的实例或 Vuex 等状态管理工具。

EventBus事件总线

事件总线是一种简单而有效的组件通信方式,它通过一个中央的事件总线来传递消息,允许不同组件之间进行解耦合的通信。它属于** 订阅/发布模式实现的一种方式,通常可以通过创建一个全局的Vue实例**作为事件总线。分为如下几个步骤:

  1. 创建事件总线实例
// eventBus.js
import Vue from 'vue';
export const EventBus = new Vue();
  1. 在父组件中发送事件,使用$emit
// 父组件
import { EventBus } from '@/utils/eventBus.js'
showDetails (val) {EventBus.$emit('message-event', '12')// 发送message-event事件,传递12这个数据},
  1. 在子组件中接收事件,使用$on
// 子组件
import { EventBus } from '@/utils/eventBus.js'
mounted() {EventBus.$on('message-event', this.doSomething)// 当message-event发生改变时,就会触发doSomething方法
},
methods() {doSomething(params) {console.log('被事件触发了此方法~')console.log('并能接收到了数据', params)}
}

事件总线
4. 为防止内存泄露,一般在组件卸载时需要解绑事件总线,使用$off

// 子组件beforeDestroy() {EventBus.$off('message-event', this.doSomething);// 解绑message-event事件},

    在解绑事件时,$off 方法的第二个参数是一个可选的回调函数。如果在 $on 时使用了具名的回调函数,可以在 $off 时只传递回调函数而省略事件名称,这样就能够更精确地解绑特定的回调函数,如:

beforeDestroy() {EventBus.$off(this.doSomething);
},
  1. 在大型应用中,为了防止命名冲突,可以考虑使用命名空间来管理事件总线。可以在 EventBus.js 中为每个模块或组件创建一个子实例,以确保事件名称的唯一性。
// EventBus.js
import Vue from 'vue';
export const ParentEventBus = new Vue();
export const ChildEventBus = new Vue();
// 父组件
import { ParentEventBus } from '@/utils/eventBus.js'

注意:
    尽量避免滥用事件总线,特别是在大型应用中。对于父子组件通信或兄弟组件通信,更推荐使用 props 和 $emit;
    在多人协作或大型项目中,可能会使用更为复杂的状态管理工具(例如 Vuex)来代替事件总线;

vuex

该方式在以往文章中已经进行了详细的讲述,请移步Vue2教程详解七(Vuex3)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/341324.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CSS 选择器全攻略:从入门到精通(上)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

制造领域 基础概念快速入门介绍

1、基本背景知识 本定义结合国家标准文件有所发挥&#xff0c;仅供参考。 产品&#xff1a;是生产企业向用户或市场以商品形式提供的制成品&#xff1b; 成套设备&#xff1a;在生产企业一般不用装配工序连接&#xff0c;但用于完成相互联系的使用功能的两个或两个以上的产…

Redis面试篇

redis面试题主要内容 面试官在面试时主要会问以下这些方面的问题 下面是一些问题示例&#xff1a; redis-使用场景 缓存 缓存穿透 介绍 缓存穿透&#xff1a;查询一个不存在的数据&#xff0c;mysql查询不到数据也不会直接写入缓存&#xff0c;就会导致每次请求都会去查数…

Java填充Execl模板并返回前端下载

功能&#xff1a;后端使用Java POI填充Execl模板&#xff0c;并返回前端下载 Execl模板如下&#xff1a; 1. Java后端 功能&#xff1a;填充模板EXECL,并返回前端 controller层 package org.huan.controller;import org.huan.dto.ExcelData; import org.huan.util.ExcelT…

c++qt-基本组件

1. Designer 设计师&#xff08;掌握&#xff09; Qt包含了一个Designer程序&#xff0c;用于通过可视化界面设计开发界面&#xff0c;保存的文件格式为.ui&#xff08;界面文件&#xff09;。界面文件内部使用xml语法的标签式语言。 在Qt Creator中创建项目时&#xff0c;选中…

Elasticsearch倒排索引详解

倒排索引&#xff1a; 组成 term index(词项索引 &#xff0c;存放前后缀指针) Term Dictionary&#xff08;词项字典&#xff0c;所有词项经过文档与处理后按照字典顺序组成的一个字典&#xff08;相关度&#xff09;&#xff09; Posting List&#xff08;倒排表&#xf…

Logback框架基本认识

文章目录 一.什么是Logback1.1 初识Logbcak 二.Logbcak的结构三.日志的级别四.配置组件详解4.1 logger 日志记录器属性的介绍如何在配置文件里配置 4.2 appender 附加器 配合日志记录器的输出格式4.2.1 控制台附加器4.2.2 文件附加器4.3.3滚动文件附加器 4.3 Filter: 过滤器&am…

Python-基础语法

标识符 第一个字符必须是字母表中字母或下划线 _ 。标识符的其他的部分由字母、数字和下划线组成。标识符对大小写敏感。在 Python 3 中&#xff0c;可以用中文作为变量名&#xff0c;非 ASCII 标识符也是允许的了。 python保留字 保留字即关键字&#xff0c;我们不能把它们用…

【开源】基于JAVA+Vue+SpringBoot的大病保险管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统配置维护2.2 系统参保管理2.3 大病保险管理2.4 大病登记管理2.5 保险审核管理 三、系统详细设计3.1 系统整体配置功能设计3.2 大病人员模块设计3.3 大病保险模块设计3.4 大病登记模块设计3.5 保险审核模块设计 四、…

[嵌入式软件][入门篇] 搭建在线仿真平台(STM32)

文章目录 一、注册平台二、创建首个项目三、硬件介绍 一、注册平台 进入官方&#xff0c;进行注册&#xff1a; 在线仿真地址 二、创建首个项目 ① 新建项目 ② 搭建一个电路 ③ 用STM32F103搭建一个简单电路 ④ 进入编码界面 三、硬件介绍 红框是必看文档&#xff…

ERROR in Plugin “react“ was conflicted .... 天坑留念-turborepo、eslint plugin

前两天项目代码拉下来&#xff0c;装完依赖启动的时候直接报错&#xff1a; [eslint] Plugin "react" was conflicted between ".eslintrc.js eslint-config-custom eslint-config-alloy/react" and "BaseConfig D:\pan\erp\test\business-servic…

在windows11系统上利用docker搭建linux记录

我的windows11系统上&#xff0c;之前已经安装好了window版本的docker&#xff0c;没有安装的小伙伴需要去安装一下。 下面直接记录安装linux的步骤&#xff1a; 一、创建linux容器 1、拉取镜像 docker pull ubuntu 2、查看镜像 docker images 3、创建容器 docker run --…