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

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

相关推荐
Moment7 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
爱敲代码的小鱼7 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax
铅笔侠_小龙虾9 小时前
Flutter 实战: 计算器
开发语言·javascript·flutter
大模型玩家七七9 小时前
梯度累积真的省显存吗?它换走的是什么成本
java·javascript·数据库·人工智能·深度学习
2501_9447114310 小时前
JS 对象遍历全解析
开发语言·前端·javascript
发现一只大呆瓜10 小时前
虚拟列表:支持“向上加载”的历史消息(Vue 3 & React 双版本)
前端·javascript·面试
阔皮大师11 小时前
INote轻量文本编辑器
java·javascript·python·c#
lbb 小魔仙11 小时前
【HarmonyOS实战】React Native 表单实战:自定义 useReactHookForm 高性能验证
javascript·react native·react.js
_codemonster11 小时前
Vue的三种使用方式对比
前端·javascript·vue.js
全栈前端老曹11 小时前
【MongoDB】Node.js 集成 —— Mongoose ORM、Schema 设计、Model 操作
前端·javascript·数据库·mongodb·node.js·nosql·全栈