之前简单做了一次vue通信方法的培训,在此记录一下培训的内容。

关于vue通信,大家最先想到的方法应该是props、ref、$emit、$parent,还有vuex,因为这也是我在项目中最常用到的方法,其实,还有其他的一些通信方法,下面我来作个简单的介绍:

我主要通过组件类型来介绍:

一、父子组件通信:

(1)父向子传值:

props: 一般用于父组件向子组件进行单向通信

ref:为子组件指定一个索引名称,通过索引来操作子组件,用this.$refs.name 获取到组件实例,可以使用组件的所有方法

$children: 父组件也可以通过this.$children 访问它所有的子组件( 需要注意 $children 并不保证顺序 )

(2)子向父传值 :

$emit:触发父组件的自定义事件 vm.$emit( event, arg )

$parent:通过this.$parent可以直接访问该组件的父实例或组件(得到最近一级的父组件)

父子组件通信实例:

//父组件
<template>
<div>
<div class="box">
<a-button @click="onClick">传参给子组件</a-button>
我是父组件,点击次数:{{ msg }}
<child ref="childRef" :msg="msg" @child-event="watchChildEvent"></child>
</div>
</div>
</template>
<script>
import Child from "./son";
export default {
components: { Child },
data() {
return {
msg: 0
};
},
methods: {
onClick() {
++this.msg;
},
//监听由子组件触发的事件,参数为子组件传来的数据
watchChildEvent(val) {
this.msg = val;
},
//监听由子组件触发的事件,参数为子组件传来的数据
watchParEvent(val) {
this.parMsg = val;
}
},
mounted() {
//父组件调用子组件方法
this.$refs.childRef.getMessage("我是子组件一");
}
};
</script>
//子组件
<template>
<div class="son-box">
<a-button @click="targetClick">通过$emit传参到父组件</a-button><br />
<a-button @click="parClick">2、通过$parent传参到父组件</a-button><br />
我是子组件1,点击次数:{{ msg }}<br />
{{ val }}
</div>
</template>
<script>
export default {
components: {},
props: {
msg: {
type: [String, Number], //类型
default: 0 //可以设置默认值
}
},
data() {
return {
val: ""
};
},
methods: {
//由子组件的事件触发 自定义事件wathChildEvent
targetClick() {
this.$emit("child-event", 20); //参数改为this.msg ??
},
//使用$parent访问父组件(得到最近一级的父组件)
parClick() {
this.$parent.watchParEvent("2、我是使用$parent更改的父级msg");
},
//由父组件的事件触发
getMessage(m) {
console.log(m);
},
},
mounted() {}
};
</script>

二、兄弟组件通信:

不使用 props 和 Vuex 时,可以用什么呢?

eventBus (中央事件总线event Bus),它允许两个子组件之间直接通讯,而不需要涉及父组件。是实现非父子组件通信的一种解决方案。但是当项目较大较复杂时,并不适合。到那时,vuex才是vue给我们提供的最理想的方式。 原理:就是创建一个vue实例,通过一个空的vue实例作为桥梁实现vue组件间的通信。(在Vue2中可谓是最好用的非父子组件之间的通讯手段,但是Vue3宣布取消了,官方推荐的做法是让用户自己寻找使用第三方库,后续有时间会分享一篇vue3如何去实现event Bus)

eventBus 的用法如下:

第一步:项目中创建一个js文件(命名为event-bus.js),引入vue,创建一个vue实例,导出这个实例,代码如下(一共就两行):

 import Vue from 'Vue'
export default new Vue

第二步:在两个需要通信的两个组件中分别引入这个event-bus.js

 import Bus from '这里是你引入event-bus.js的路径' // Bus可自由更换喜欢的名字

第三步:传递数据的组件里通过vue实例方法$emit发送事件名称和需要传递的数据。(发送数据组件)

Bus.$emit('click',data) // 这个click是一个自定义的事件名称,data就是你要传递的数据。

第四步:被传递数据的组件内通过vue实例方法$on监听到事件和接受到数据。(接收数据的组件)这里通常挂载监听在vue生命周期created和mounted当中的一个,具体使用场景需要具体的分析,这里不说这个。

Bus.$on('click',target => {
 console.log(target) //注意:发送和监听的事件名称必须一致,target就是获取的数据,可以不写target。(自己命名)
})

通过以上的四步其实就已经实现了最简单的eventbus的实际应用了。

但是到这儿后,一定要注意一个最容易忽视,又必然不能忘记的东西,那就是清除事件总线eventBus. 不手动清除,它是一直会存在的,这样的话,有个问题就是反复进入到接受数据的组件内操作获取数据,原本只执行一次的获取的操作将会有多次操作。如上我所举的例子,会打印多次传过来的数据。但你想想,实际开发中是不会这么简单的打印这个数据到控制台,本来只会触发并只执行一次,现在变成了多次,这个问题就非常严重了,你们各种脑补具体的项目开发场景吧。

第五步:在vue生命周期beforeDestroy或者destroyed中用vue实例的$off方法清除eventBus

beforeDestroy(){
bus.$off('click')
}

 

三、跨多层级组件通信

A-B-C,三个组件,从爷组件A传参到孙组件C,应该怎么传呢?

(1)通过props一层层传递过去,传到子,给传给孙

(2)用vuex 共享状态(开发大型单页应用)

(3)使用$attrs传参,$listeners监听事件,或者用provide 和 inject

 1、$attrs和$listeners的介绍:

  • $attrs是在vue的2.40版本以上添加的。
  • 所有的非props属性,都可以通过 v-bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用。
  • 多层组件传参使用$attrs,可以使代码更加美观,更加简洁,维护代码的时候更方便。如果使用普通的父子组件传参prop会很繁琐;如果使用vuex会大材小用,只是在这几个组件中使用,没必要使用vuex;使用事件总线eventBus,使用不恰当的话,有可能会出现事件多次执行。
  • 所有组件上的方法绑定子组件都可以通过$listeners接收
  • 详情可查看:vue.js-$attrs
注意:
1、vue2中使用$attrs从父组件传递数据给子组件嵌套组件,父组件通过通过$listeners监听子组件的事件
2、vue3把把$attrs和$listeners统一合并到$attrs中

  

props的劣势: 父组件传入子组件属性,但子组件没有接收称为非props属性,非props属性默认会加到子组件标签最外层

inheritAttrs: false的含义是不希望本组件的根元素继承父组件的attribute,同时父组件传过来的属性(没有被子组件的props接收的属性),也不会显示在子组件的dom元素上,但是在组件里可以通过其$attrs可以获取到没有使用的注册属性, inheritAttrs: false是不会影响 style 和 class 的绑定

$listeners的实例:

所有组件上的方法绑定子组件都可以通过$listeners接收。它可以通过 v-on="$listeners" 将所有的方法又绑定到组件相应标签,传入内部组件——在创建更高层次的组件时非常有用。

2、provide 和 inject的介绍与实例:

provide和inject是在2.2.0 版本新增的,主要为高阶插件/组件库提供用例。这对选项需要一起使用,以允许一个祖先组件向其所有的子孙后代注入一个依赖,不论组件的层次有多深,并在起上下游关系成立的时间里始终生效。

provide 选项应该是一个对象或返回一个对象的函数。该对象包含可注入其子孙的属性。

inject 选项应该是:一个字符串数组,或一个对象(属性值是一个对象时,包含from和default默认值)

注意:provide和inject绑定并不是可响应的。这显然不是设计的失误,而是刻意的。如果要详细了解,请参考:API — Vue.js

我们在上级组件中设置了一个provide:foo,值为beijing,它的作用就是将foo这个变量提供给它的所有下级组件。而在下级组件中通过inject注入了从上级组件中提供的foo变量,那么在下级组件中,就可以直接通过this.foo来访问了

provide 和 inject的实例:

如果想要获取父组件parent.vue 的多个属性或方法时,我们应该怎么传呢?是一个个的定义参数传过去吗?

parent.vue作为一个最外层的根组件,用来存储所有需要的全局数据和状态。我们可以把整个parent.vue实例通过provide对外提供。那么,所有的子组件、孙组件都能共享其数据,方法等。

 四、VUEX状态管理

内容太多,将在下篇单独做介绍

vue 通信:父子通信、兄弟通信、跨多层通信、vuex状态管理的更多相关文章

  1. vue第十八单元(单向数据流 vuex状态管理)

    第十八单元(单向数据流 vuex状态管理) #课程目标 1.理解什么是数据管理模式 2.什么是vuex 3.什么时候使用vuex 4.vuex安装及工作原理 5.vuex语法 #知识点 1.首先来看下 ...

  2. 前端MVC Vue2学习总结(八)——Vue Router路由、Vuex状态管理、Element-UI

    一.Vue Router路由 二.Vuex状态管理 三.Element-UI Element-UI是饿了么前端团队推出的一款基于Vue.js 2.0 的桌面端UI框架,手机端有对应框架是 Mint U ...

  3. 前端Vue框架-vuex状态管理详解

    新人报道!多多关照-多提宝贵意见 谢谢- vuex理解 采用集中式存储管理模式.用来管理组件的状态,并以自定义规则去观测实时监听值得变化. 状态模式管理理解 属性 理解 state 驱动应用的数据源 ...

  4. Vuex状态管理——任意组件间通信

    核心概念 在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信. 每一个 Vuex 应用的 ...

  5. vue组件化开发-vuex状态管理库

    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化.Vuex 也集成到 Vue 的官方调试工具 ...

  6. vue从入门到进阶:Vuex状态管理(十)

    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化. 在 Vue 之后引入 vuex 会进行自动 ...

  7. 应用四:Vue之VUEX状态管理

    (注:本文适用于有一定Vue基础或开发经验的读者,文章就知识点的讲解不一定全面,但却是开发过程中很实用的) 概念:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应 ...

  8. vue项目--vuex状态管理器

    本文取之官网和其他文章结合自己的理解用简单化的语言表达.用于自己的笔记记录,也希望能帮到其他小伙伴理解,学习更多的前端知识. Vuex 是什么? Vuex 是一个专为 Vue.js 应用程序开发的状态 ...

  9. 【Flutter学习】组件通信(父子、兄弟)

    一,概述 flutter一个重要的特性就是组件化.组件分为两种状态,一种是StatefulWidget有状态组件,一种是StatelessWidget无状态组件. 无状态组件不能更新状态,有状态组件具 ...

随机推荐

  1. python——虚拟环境管理大合集

    个人常用:pipenv 安装 pip3 install pipenv 创建虚拟环境 # 默认安装在~/.local/virtualenv下 mkdir project cd project pipen ...

  2. 一加6刷入kali nethunter

    Installing Kali NetHunter On the OnePlus 6 准备工具: adb: https://jingyan.baidu.com/article/22fe7cedf67e ...

  3. 国产操作系统deepin安装与配置Node-RED环境

    1.1. 测试机配置清单 部件名称 版本号 备注 处理器 Intel Core i5 3320M 显卡 自带集显 内存 8G DDR3单通道 显示插口 VGA*1,HDML*1 1.2. 系统安装及配 ...

  4. VC709E 基于FMC接口的FPGA XC7VX690T PCIeX8 接口卡

    一.板卡概述 本板卡基于Xilinx公司的FPGA XC7VX690T-FFG1761 芯片,支持PCIeX8.两组 64bit DDR3容量8GByte,HPC的FMC连接器,板卡支持各种FMC子卡 ...

  5. Solution -「JOISC 2021」「LOJ #3491」道路建设

    \(\mathcal{Description}\)   Link.   平面上有 \(n\) 个互不重合的点 \((x_{1..n},y_{1..n})\),求其两两曼哈顿距离的前 \(m\) 小值. ...

  6. Solution -「APIO/CTSC 2007」「洛谷 P3620」数据备份

    \(\mathcal{Description}\)   Link.   给定升序序列 \(\{x_n\}\) 以及整数 \(k\),在 \(\{x_n\}\) 中选出恰 \(k\) 对 \((x_i, ...

  7. Nginx服务器SSL证书安装

    操作场景 本文档指导您如何在 Nginx 服务器中安装 SSL 证书. 说明: 本文档以证书名称 www.domain.com 为例. Nginx 版本以 nginx/1.16.0 为例. 当前服务器 ...

  8. vue的编译作用域

    其实就是在哪个实例中使用vue指令,他所在的作用域就在那个实例中 例如 当组件标签使用vue指令的时候,他所在的作用域就是vue实例对象的作用域,而当组件的 template中 标签使用vue指令的话 ...

  9. BeanFactory与FactoryBean有什么区别?

    相同点:都是用来创建bean对象的 不同点:使用beanFactory创建对象的时候,必须要遵循严格的生命周期流程,太复杂了,如果想要简单的自定义某个对象的创建,同时创建好的对象想要交给spring来 ...

  10. unittest测试框架,HTMLTestReportCN模块生成的测试报告中展示用例说明的配置方法

    1.前言 想要生成的html测试报告中展示每个测试用例的说明信息,方便了解测试案例的测试点或者其他信息,目前知道的有2种 2.方法介绍 * 方法1: 要添加说明的测试用例,将说明信息用3个引号包裹起来 ...