vue-组件间通信
抽个小空,写个总结。方便以后查看
有不对的,请指出,非常感谢;
1.父子组件通信
- 父组件 =》子组件
- props
在父组件中:
调用子组件的时候,将msg传递 可以是变量 用:
1 | <tips :msg= "msg" ></tips> |
在子组件中:
通过props接受父组件传递过来的数据 :msg
1 2 3 4 5 6 7 8 9 | //template代码 <div class = "myalert" > {{msg}} <a class = "close" @click= "closeFn" >确定</a> </div> //js代码 props:{ msg:{require: true } }, |
2.refs
父组件中:
用 ref 标记子组件 <test msg= "测试数据" ref = "test" ></test> js代码 通过$refs找到子组件 实例 并调用子组件的方法,并传参 this .$refs.test.showFn( 'test' ); |
子组件中:
1 2 3 4 5 | 子组件的定义的方法 showFn(msg){ this .showFlag= true ; this .msg=msg } |
2. 子组件 =》父组件
$emit 调用父组件中的方法,并传参
父组件中:
1 2 3 4 5 6 7 8 9 10 | template代码 将父组件中的changeShowTips 方法传入 <tips :msg= "msg" @changeShowTips= "changeShowTips" v-show= "showTipsFlag" ></tips> js代码 changeShowTips(data) { this .showTipsFlag = data; }, |
子组件中:
1 2 3 4 5 6 7 8 | <div class = "myalert" > {{msg}} <a class = "close" @click= "closeFn" >确定</a> </div> js调用 子组件中 利用$emit调用父组件中的方法,并传参 closeFn(){ this .$emit( 'changeShowTips' , false ); } |
2.兄弟组件
结构: tips和test共同在一个父组件中
在父组件中:定了一个一个fn函数 ,但是fn的处理函数是在$on之后的函数 这里写不管用
1 | fn() {}, |
在tips.vue中
1 2 3 4 | 在mounted 或者其他生命周期函数中,或者事件中 让父组件监听了fn这个函数 后面是他的处理函数 就可以接收到 兄弟组件 通过 this .parent.$emit(fn)传来的值<strong> this .$parent.$ on ( "fn" ,</strong> function(msg) { this .msg = msg; 这里的msg是兄弟组件传来的值 }); |
//这是兄弟组件触发事件以后的处理函数
test.vue中 有一个可以改变tips组件数据的方法 ,其原理就是通过父组件调用改变方法
1 2 3 | changTipsFn() { <strong> this .$parent.$emit( "fn" , "123" );</strong> } |
原理就是 父组件 动态监听了 一个函数fn的调用,当组件a调用了这个fn,则父组件拿到fn的值,并进行处理(改变了组件b的内容),只不过这个过程 父组件并没有直接参与,而是两个子组件,通过this.$parent来实现;
也可以用this.$root实现
3.祖先和后代
- 祖先 =》后代
provide / inject 需要一起使用,允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效
provide Object | () => Object
inject Array<string> | { [key: string]: string | Symbol | Object } 一个字符串数组,或 一个对象,对象的 key 是本地的绑定名
provide 和 inject 主要在开发高阶插件/组件库时使用。并不推荐用于普通应用程序代码中。
provide
inject
1 2 3 4 5 6 | provide() { return { common: { my_data: this .obj } // 提示:provide 和 inject 绑定并不是可响应的。是刻意为之的。如果你传入了一个可监听的对象,那么其对象的属性还是可响应的。这里的obj就是父组件中定义的可响应的数据 }; }, |
子组件:
1 2 3 4 5 6 7 8 9 10 | inject: { common: { default : () => { return {my_data: '0' } } } }, 使用: {{ common.my_data.title }} |
2.后代 =》祖先
原理:递归查找父组件 通过$emit和$on进行传值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | // 定义一个dispatch方法,指定要派发事件名称和数据 function dispatch(eventName, data) { let parent = this .$parent // 只要还存在父元素就继续往上查找 while (parent) { // 父元素用$emit触发 <strong>parent.$emit</strong>(eventName,data) // 递归查找父元素 <strong>parent = parent.$parent </strong> } } 调用: // child.vue 子组件嗲用dispatch hello 方法是父组件的 <h1 @click= "dispatch('hello', 'hello,world')" >{{ msg }}</h1> // parent.vue this .$ on ( 'hello' , this .sayHello) mounted() { // 父组件中监听hello,执行相应的this.sayHello方法 从而试得父组件接收到子组件的数据 this .$ on ( "hello" , this .sayHello); }, sayHello(msg) { alert(msg); }, hello(msg) { console.log(msg + "触发了父元素的事件" ); 并没有打印 } |
每一级的parent我都打印了
一般不会这样做
4.任意组件
- vuex
- 事件总线:vue-bus 创建一个Bus类父组事件派发,监听和回调管理
事件总线:
原理:
在bus这个vue对象中注册foo事件,根据emit源码遍历执行所有名为foo的事件。当我们在b组件emit 分发事件后再a组件注册事件就将被执行 cbs[i].apply(vm, args);,再a组件的参数就将赋值给a组件中的data,根据vue数据绑定原理 此时this.bus的set()方法被触发,遍历bus属性在get()方法中收集到的依赖,并更新依赖,此时数据就从一个vue对象传递到另一个vue对象
1. 在assets中创建一个bus.js
1 2 | import Vue from 'vue' export default new Vue; |
在需要的组件中引入
1 | import bus from "../assets/bus" ; |
事件触发
1 2 | bus.$emit( "foo" ); 此处 foo 是自定义名称,并没有实际作用;确保需要响应变化的组件 通过监听同名字 从而达到变化的效果 |
需要同步做出改变的组件
1 2 3 4 5 6 7 8 | mounted() { bus.$ on ( "foo" , function() { console.log( "监听到了bus" ); }); }, 监听foo 变化 组件a触发了foo ,组件b监听到foo,从而做出改变 完成任意组件间通信 需要通信的组件都需要引入bus |
2. 手写bus 非通过vue实例的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | // Bus:事件派发、监听和回调管理 class Bus { constructor() { //{ // eventName1:[fn1,fn2], // eventName2:[fn3,fn4], // //} this .callbacks = {} } $ on (name, fn) { this .callbacks[name] = this .callbacks[name] || [] this .callbacks[name].push(fn) } $emit(name, args) { if ( this .callbacks[name]) { this .callbacks[name].forEach(cb => cb(args)) } } } // main.js Vue.prototype.$bus = new Bus() // child1 this .$bus.$ on ( 'foo' , handle) // child2 this.$bus.$emit('foo') |
补充知识点:
vm.$emit( event, arg ) //触发当前实例上的事件
vm.$on( event, fn );//监听event事件后运行 fn;
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· C# 深度学习:对抗生成网络(GAN)训练头像生成模型
· .NET 适配 HarmonyOS 进展
· 手把手教你更优雅的享受 DeepSeek
· AI工具推荐:领先的开源 AI 代码助手——Continue
· 探秘Transformer系列之(2)---总体架构
· V-Control:一个基于 .NET MAUI 的开箱即用的UI组件库
· 乌龟冬眠箱湿度监控系统和AI辅助建议功能的实现