vue组件之间通信总结(超详细)
组件通信在我们平时开发过程中,特别是在vue和在react中,有着举足轻重的地位。本篇将总结在vue中,组件之间通信的几种方式:
- props、$emit
- $parent、$children
- $attrs、$listeners
- provide、inject
- eventBus
- vuex
- 本地存储
一、props、$emit单向数据流

father.vue:
<template>
<div>
<div>我是父亲:<input type="button" value="父亲" /> 数字为: {{num}}</div>
<son :num="num" @change="change"></son>
</div>
</template> <script>
import son from "./son.vue";
export default {
name: "Father",
components: {
son,
},
data() {
return {
num: 1,
};
},
methods:{
change(val){
this.num = val
}
}
};
</script>
son.vue:
<template>
<div>我是儿子:<input type="button" value="儿子" @click="change"/>数字为:{{num}}</div>
</template> <script>
export default {
name: "App",
components: {},
props: {
num: {
default: 0,
},
},
created() {},
methods: {
change(){
// this.num = 2 props通信是单向数据流,在这直接修改父组件传过来的num将会帮错
// 可以用$emit传递change事件,father组件绑定change事件
this.$emit('change', 2)
}
},
};
</script>

对于上面的场景:子组件的change事件只是为了修改父组件中某一个值,还可以有以下几种写法:
1.父组件绑定给子组件的事件使用箭头函数
father:
<son :num="num" @change="val => num = val"></son> son:
this.$emit('change', 2)
2.update:num和.sync
father:
<son :num.sync="num"></son>
son:
this.$emit('update:num', 2)//update是规定的写法,不可更换
3.v-model
先修改props和绑定的事件:
father:
<son :value="num" @input="val => num = val"></son>
son:
this.$emit('input', 2)
可用v-model简写:
<son v-model="num"></son>
二、$parent、$children
$parent、$children可直接在父子组件中调用各自的方法以及修改数据
子组件中直接:this.$parent.num = 2
父组件中需要用ref来选中指定的子组件
vue官方并不推荐使用这种通信方式:节制地使用 $parent 和 $children - 它们的主要目的是作为访问组件的应急方法,更推荐用 props 和 events 实现父子组件通信。
三、$attrs、$listeners
$attrs可以拿到父组件传过来的属性:
<div>我是儿子:<input type="button" value="儿子" @click="change"/>数字为:{{$attrs}}</div>

dom节点:

$attrs会直接将传过来的属性放到对应的标签上,反观props就不会。如果想去掉标签中的这些属性,可以用inheritAttrs:

值得注意的是:props的优先级大于$attrs,即当props存在的时候,$attrs为空对象:

$attrs常用于跨多级组件传递属性,比如祖孙组件,用父组件做中转:
father:
<son v-bind="$attrs"></son>
$attrs用于属性跨级传递,方法跨级传递则用$listeners。
grandFather.vue:
<template>
<div>
<div>我是祖父: 数字为:{{nums}}</div>
<father :nums="nums" @up="up" @down="down"></father>
</div>
</template> <script>
import father from "./father.vue";
export default {
name: "App",
components: {
father,
},
data(){
return {
nums:0
}
},
methods: {
up() {
alert('up')
},
down() {
alert('down')
},
},
};
</script>
father.vue:
<son v-bind="$attrs" v-on="$listeners"></son>
son.vue:
<div>我是儿子:<input type="button" value="儿子" @click="$listeners.up"/></div>

四、provide、inject
这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在其上下游关系成立的时间里始终生效
provide选项应该是一个对象或返回一个对象的函数。
inject选项应该是一个字符串数组或一个对象。
App:
...
export default {
provide(){
return {vm: this}
},
...
son:
...
export default {
inject: ['vm'],
data(){},
mounted(){
console.log(this.vm)
}
...

注意:provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的 property 还是可响应的。
inject注入中的值会沿着组件向上查找,遵从"就近原则"。
provide 和 inject中的数据流是双向的。
五、eventBus(事件总线)
eventBus通过发布订阅全局事件,供其他组件使用。
在main.js中:
Vue.prototype.$bus = new Vue();
parent.vue:
<template>
<div>
<son1></son1>
<son2></son2>
</div>
</template> <script>
import son1 from './son1.vue'
import son2 from './son2.vue'
export default {
name: 'parent',
components: {
son1,
son2
},
created(){
this.$bus.$on('busEvent',(v)=>{
console.log(v);
})
},
beforeDestroy(){
this.$bus.off('busEvent')
}
}
</script>
son1和son2中的mounted:
son1:
mounted(){
this.$bus.$emit('busEvent','son1哈哈')
}
son2:
mounted(){
this.$bus.$emit('busEvent', 'son2嘻嘻')
}
打印结果:

使用eventBus有两点需要注意,1.$bus.on应该在created钩子内使用,如果在mounted使用,它可能接收不到其他组件来自created钩子内发出的事件;
2.$bus.emit应该在mounted中使用,等待created中的$bus.on事件绑定完成;
3.发布订阅的事件在beforeDestory钩子里需要使用$bus.off解除,组件销毁后没必要一直监听。
接下来还有vuex和storage实现组件通信,明天补上~
脚踏实地行,海阔天空飞~
vue组件之间通信总结(超详细)的更多相关文章
- 前端面试 vue 部分 (5)——VUE组件之间通信的方式有哪些
VUE组件之间通信的方式有哪些(SSS) 常见使用场景可以分为三类: 父子通信: null 父向子传递数据是通过 props ,子向父是通过 $emit / $on $emit / $bus Vuex ...
- Vue 组件之间通信 All in One
Vue 组件之间通信 All in One 组件间通信 1. 父子组件之间通信 https://stackblitz.com/edit/vue-parent-child-commutation?fil ...
- vue组件之间通信传值
原文链接:https://blog.csdn.net/lander_xiong/article/details/79018737 我认为这位博主的这篇文章写的非常详细,通俗易懂, 我们这次的vue项目 ...
- Vue组件之间通信的三种方式
最近在看梁颠编著的<Vue.js实战>一书,感觉颇有收获,特此记录一些比价实用的技巧. 组件是MVVM框架的核心设计思想,将各功能点组件化更利于我们在项目中复用,这类似于我们服务端面向对象 ...
- vue组件之间通信的8种方式
对于vue来说,组件之间的消息传递是非常重要的,下面是我对组件之间消息传递的常用方式的总结. props和$emit(常用) $attrs和$listeners 中央事件总线(非父子组件间通信) v- ...
- Vue组件之间通信
vue组件传值有以下几种情况: 父组件向子组件传值.子组件向父组件传值.兄弟组件之间传值等 一.父组件向子组件传值: 传值方式: props <father> // 动态传递值 <s ...
- vue组件之间通信总结---点赞
总结:父组件-->子组件 ①通过属性 步骤1: <son myName="michael" myPhone='123'></son> <son ...
- vue 组件之间通信
父传子 **父组件代码** <template> <header-box :title-txt="showTitleTxt"></header-box ...
- 【Vue课堂】Vue.js 父子组件之间通信的十种方式
这篇文章介绍了Vue.js 父子组件之间通信的十种方式,不管是初学者还是已经在用 Vue 的开发者都会有所收获.无可否认,现在无论大厂还是小厂都已经用上了 Vue.js 框架,简单易上手不说,教程详尽 ...
随机推荐
- Django(56)Mixins工具集的使用
前言 mixins翻译成中文是混入,组件的意思.在DRF中,针对获取列表,检索,创建等操作,都有相应的mixin,一般我们自定义创建的类视图都会继承自GenericAPIView和Mixins一起使用 ...
- Httprunner的使用
一.httprunner的简介 HttpRunner 是一款面向 HTTP(S) 协议的通用测试框架,只需编写维护一份 YAML/JSON 脚本,即可实现自动化测试.性能测试.线上监控.持续集成等多种 ...
- Git操作_本地仓库第一次推送到远程仓库
实现目的: 本地已经安装好Git,pycham已经有一个项目,打算放到Git远程仓库 前提条件:本地配置好了公钥,且GIT 上关联好公钥,步骤如下: git本地仓库连接github操作步骤:windo ...
- 【NX二次开发】设置了“附加包含目录”,还是提示“无法打开包括文件”的解决方法
项目属性中的"附加包含目录"路径完全正确,但是还是无法找到头文件: 这个问题我遇到过不止一次,纠结了很久,终于发现了解决方法: 改为: 问题解决! 分析原因:项目中的属性配置 与 ...
- 《吃透MQ系列》之扒开Kafka的神秘面纱
大家好,这是<吃透 MQ 系列>的第二弹,有些珊珊来迟,后台被好几个读者催更了,实属抱歉! 这篇文章拖更了好几周,起初的想法是:围绕每一个具体的消息中间件,不仅要写透,而且要控制好篇幅,写 ...
- 史上最详细的Air7xx驱动安装教程
由于Air7xx系列4G模块需要安装USB驱动,但是很多开发者对USB驱动的安装方法不是十分了解,所以经常出现问题,导致安装失败.特书此文,手把手教你装USB驱动. 第一步 从官网下载最新的驱动程序 ...
- 【模拟7.16】通讯(tarjan缩点加拓扑排序)
这题确实水,纯板子,考试意外出错,只拿了暴力分QAQ tarjan缩点加上拓扑排序,注意这里求最短路径时不能用最小生成树 因为是单向边,不然就可能不是一个联通图了.... 1 #include< ...
- Windows内核开发-Windows内部概述-1-
Windows内部概述-1- 进程: 进程是一个程序的运行实例的控制和管理对象.一般的程序员所说进程运行,这样的说法是不对的,因为进程不能运行程序,进程只能管理该程序运行.线程才是真正的执行代码的东西 ...
- K8s 部署 Prometheus + Grafana
一.简介 1. Prometheus 一款开源的监控&报警&时间序列数据库的组合,起始是由 SoundCloud 公司开发的 基本原理是通过 HTTP 协议周期性抓取被监控组件的状态, ...
- Windows下安装kubectl及Node和Pod操作常用命令
kubernetes通过kube-apiserver作为整个集群管理的入口.Apiserver是整个集群的主管理节点,用户通过Apiserver配置和组织集群,同时集群中各个节点同etcd存储的交互也 ...