Vue组件通信的N种姿势,你Pick哪一种?🚀

大家好,我是小杨,一个写了6年前端的老司机。今天聊聊Vue组件通信------这玩意儿就像谈恋爱,得找到合适的沟通方式,不然容易吵架(Bug)!

一、父子组件:Props & Events(最基础,但够用)

场景:爸爸(父组件)要给儿子(子组件)零花钱,儿子要告诉爸爸考试考了多少分。

javascript 复制代码
// 父组件:给钱(传递数据)
<ChildComponent :money="100" @score-change="handleScoreChange" />

methods: {
  handleScoreChange(score) {
    console.log('我儿子考了:', score)
  }
}

// 子组件:收钱 + 汇报成绩
props: ['money'],
methods: {
  reportScore() {
    this.$emit('score-change', 90) // 触发事件
  }
}

适用 :简单直接的上下级关系,但隔代组件用这个会累死(Prop逐层传递警告!)。


二、爷孙组件: <math xmlns="http://www.w3.org/1998/Math/MathML"> a t t r s / attrs / </math>attrs/listeners(隔代传值神器)

场景:爷爷想跳过爸爸直接给孙子塞红包(禁止套娃!)。

javascript 复制代码
// 爷爷组件
<ParentComponent :money="200" :message="'好好学习'" />

// 爸爸组件(中间人,不处理props)
<ChildComponent v-bind="$attrs" />  

// 孙子组件
created() {
  console.log(this.$attrs) // { money: 200, message: "好好学习" }
}

优点 :不用在中间组件一层层声明props,适合高阶组件封装


三、全局事件总线(EventBus):任意组件撩骚

场景:两个毫无关系的组件突然要交换数据(比如A组件点了按钮,B组件要响应)。

javascript 复制代码
// 创建EventBus(通常单独一个文件)
export const eventBus = new Vue()

// A组件发送事件
eventBus.$emit('表白', { name: '我', words: '今晚吃鸡吗?' })

// B组件接收
eventBus.$on('表白', data => {
  console.log(data.words) // 输出:今晚吃鸡吗?
})

注意 :记得在beforeDestroy里用eventBus.$off()取消监听,否则可能内存泄漏


四、Vuex:中央情报局(适合复杂应用)

场景:多个组件要共享用户登录状态、购物车数据等。

javascript 复制代码
// store.js
state: { userName: '我' },
mutations: {
  updateName(state, newName) {
    state.userName = newName // 同步修改
  }
}

// 任意组件修改
this.$store.commit('updateName', '新名字')

// 任意组件读取
computed: {
  userName() {
    return this.$store.state.userName
  }
}

什么时候用?

  • 中大型项目
  • 频繁跨组件共享数据
  • 需要持久化的状态(比如用户Token)

五、Provide / Inject:土豪长辈的遗产继承

场景 :祖传的VIP会员身份,后代组件直接继承,不用层层传递。

javascript 复制代码
// 祖先组件
provide() {
  return { vipLevel: '钻石会员' }
}

// 后代组件(任意层级)
inject: ['vipLevel'],
created() {
  console.log(this.vipLevel) // 钻石会员
}

慎用 :这相当于全局变量,容易导致数据来源不清晰,适合主题配置、国际化等场景。


六、$refs:直接操作组件(简单粗暴)

场景:父组件要直接调用子组件的方法(比如让视频播放器暂停)。

javascript 复制代码
<VideoPlayer ref="videoPlayer" />

methods: {
  handlePause() {
    this.$refs.videoPlayer.pause() // 直接调用子组件方法
  }
}

缺点:破坏了组件封装性,相当于:"儿子,老子命令你立刻写作业!"


七、终极对比表

方式 适用场景 优点 缺点
Props / Events 父子组件简单通信 直观、官方推荐 跨层级麻烦
EventBus 任意组件通信 灵活、解耦 需手动管理监听
Vuex 中大型项目状态管理 集中管理、响应式 略重
Provide / Inject 跨层级共享配置 避免逐层传递 数据来源不透明

八、我的踩坑实录

  1. EventBus忘记销毁:曾经有个页面反复创建/销毁,导致事件重复监听,结果点一次按钮触发N次回调...
  2. Vuex滥用:把本应是组件自身状态的数据塞到Vuex里,导致维护时想打自己。

黄金法则:根据场景选择最简单的方案,别为了用而用!

⭐ 写在最后

请大家不吝赐教,在下方评论或者私信我,十分感谢🙏🙏🙏.

✅ 认为我某个部分的设计过于繁琐,有更加简单或者更高逼格的封装方式

✅ 认为我部分代码过于老旧,可以提供新的API或最新语法

✅ 对于文章中部分内容不理解

✅ 解答我文章中一些疑问

✅ 认为某些交互,功能需要优化,发现BUG

✅ 想要添加新功能,对于整体的设计,外观有更好的建议

✅ 一起探讨技术加qq交流群:906392632

最后感谢各位的耐心观看,既然都到这了,点个 👍赞再走吧!

相关推荐
xiaoqi92218 分钟前
React Native鸿蒙跨平台如何实现分类页面组件通过searchQuery状态变量管理搜索输入,实现了分类的实时过滤功能
javascript·react native·react.js·ecmascript·harmonyos
qq_1777673741 分钟前
React Native鸿蒙跨平台实现应用介绍页,实现了应用信息卡片展示、特色功能网格布局、权限/联系信息陈列、评分展示、模态框详情交互等通用场景
javascript·react native·react.js·ecmascript·交互·harmonyos
2603_949462101 小时前
Flutter for OpenHarmony社团管理App实战:预算管理实现
android·javascript·flutter
wuhen_n1 小时前
JavaScript内存管理与执行上下文
前端·javascript
Hi_kenyon1 小时前
理解vue中的ref
前端·javascript·vue.js
jin1233222 小时前
基于React Native鸿蒙跨平台地址管理是许多电商、外卖、物流等应用的重要功能模块,实现了地址的添加、编辑、删除和设置默认等功能
javascript·react native·react.js·ecmascript·harmonyos
2501_920931702 小时前
React Native鸿蒙跨平台医疗健康类的血压记录,包括收缩压、舒张压、心率、日期、时间、备注和状态
javascript·react native·react.js·ecmascript·harmonyos
橙露3 小时前
React Hooks 深度解析:从基础使用到自定义 Hooks 的封装技巧
javascript·react.js·ecmascript
2501_920931704 小时前
React Native鸿蒙跨平台使用useState管理健康记录和过滤状态,支持多种健康数据类型(血压、体重等)并实现按类型过滤功能
javascript·react native·react.js·ecmascript·harmonyos
Ulyanov4 小时前
从静态到沉浸:打造惊艳的Web技术发展历程3D时间轴
前端·javascript·html5·gui开发