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逐层传递警告!)。


二、爷孙组件: a t t r s / attrs / 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

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

相关推荐
meilindehuzi_a3 分钟前
深入理解 JavaScript 的同步与异步机制:从单线程设计到 Promise 核心应用
开发语言·javascript·ecmascript
如烟花的信页5 分钟前
加速乐cookie逆向分析
javascript·爬虫·python·js逆向
永远的WEB小白11 分钟前
css改变svg图标的颜色
前端·javascript·css
ikoala30 分钟前
Codex 不得不装的 12 个插件,都在这了
前端·javascript·后端
赵庆明老师1 小时前
JS检查提交的文件是否合规
开发语言·前端·javascript
颂love1 小时前
Vue的两大生态以及组件通信
前端·javascript·vue.js·typescript
光影少年2 小时前
js单线程,为什在node环境下的js可以处理高并发请求?
前端·javascript·掘金·金石计划
moMo2 小时前
# JavaScript 的“等等我”:聊聊同步与异步
javascript
Cobyte2 小时前
19.Vue Vapor 的实现原理原来这么简单
前端·javascript·vue.js
JackieDYH2 小时前
uniapp vue3 常用的生命周期和作用使用时机
javascript·vue.js·uni-app