🔥 Vue组件传值:小杨教你玩转父子组件通信

大家好,我是江城开朗的豌豆,一名拥有6年以上前端开发经验的工程师。我精通HTML、CSS、JavaScript等基础前端技术,并深入掌握Vue、React、Uniapp、Flutter等主流框架,能够高效解决各类前端开发问题。在我的技术栈中,除了常见的前端开发技术,我还擅长3D开发,熟练使用Three.js进行3D图形绘制,并在虚拟现实与数字孪生技术上积累了丰富的经验,特别是在虚幻引擎开发方面,有着深入的理解和实践。

我一直认为技术的不断探索和实践是进步的源泉,近年来,我深入研究大数据算法的应用与发展,尤其在数据可视化和交互体验方面,取得了显著的成果。我也注重与团队的合作,能够有效地推动项目的进展和优化开发流程。现在,我担任全栈工程师,拥有CSDN博客专家认证及阿里云专家博主称号,希望通过分享我的技术心得与经验,帮助更多人提升自己的技术水平,成为更优秀的开发者。

技术qq交流群:906392632

大家好,我是小杨,一个做了6年前端的老司机。今天咱们来聊聊Vue中组件传值那些事儿,这可是Vue开发中最基础也最常用的技能之一。掌握了这些技巧,你的组件之间就能愉快地"聊天"了!

为什么需要组件传值?

想象一下,我开发了一个电商网站,商品列表组件需要把用户选中的商品信息传递给购物车组件,这就是典型的组件通信场景。Vue提供了多种传值方式,咱们一个个来看。

1. 父传子:Props大法好

这是最常用的方式,就像爸爸给儿子零花钱一样简单。

html 复制代码
<!-- 父组件 -->
<template>
  <div>
    <child-component :money="myMoney" />
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue'

export default {
  components: { ChildComponent },
  data() {
    return {
      myMoney: 1000 // 这是我的私房钱
    }
  }
}
</script>

<!-- 子组件 -->
<template>
  <div>爸爸给了我 {{ money }} 块钱</div>
</template>

<script>
export default {
  props: {
    money: {
      type: Number,
      default: 0
    }
  }
}
</script>

注意点:

  • Props是单向数据流,子组件不能直接修改父组件传过来的值
  • 可以用.sync修饰符实现"双向绑定"的效果(Vue 2.x)
  • Vue 3中推荐用v-model替代.sync

2. 子传父:自定义事件

儿子要钱花,得跟爸爸打个招呼不是?

html 复制代码
<!-- 子组件 -->
<template>
  <button @click="askForMoney">爸,我没钱吃饭了</button>
</template>

<script>
export default {
  methods: {
    askForMoney() {
      this.$emit('give-me-money', 200) // 触发自定义事件
    }
  }
}
</script>

<!-- 父组件 -->
<template>
  <div>
    <child-component @give-me-money="handleGiveMoney" />
    <p>儿子要了 {{ givenMoney }} 块钱</p>
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue'

export default {
  components: { ChildComponent },
  data() {
    return {
      givenMoney: 0
    }
  },
  methods: {
    handleGiveMoney(amount) {
      this.givenMoney = amount
      console.log('这小子又要钱!')
    }
  }
}
</script>

3. 兄弟组件通信:Event Bus

两兄弟之间直接传话,不用经过老爸了!

js 复制代码
// eventBus.js
import Vue from 'vue'
export const EventBus = new Vue()

// 兄弟组件A
<script>
import { EventBus } from './eventBus'

export default {
  methods: {
    tellBrother() {
      EventBus.$emit('message', '妈让你回家吃饭')
    }
  }
}
</script>

// 兄弟组件B
<script>
import { EventBus } from './eventBus'

export default {
  created() {
    EventBus.$on('message', (msg) => {
      console.log(`哥哥说:${msg}`)
    })
  }
}
</script>

注意: Vue 3中因为移除了$on等方法,推荐使用mitt等第三方库替代Event Bus。

4. Vuex:全局状态管理

家里事儿太多太乱?上个家庭管理系统!

js 复制代码
// store.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    familyMoney: 10000 // 家庭总资产
  },
  mutations: {
    spendMoney(state, amount) {
      state.familyMoney -= amount
    }
  },
  actions: {
    buySomething({ commit }, amount) {
      commit('spendMoney', amount)
    }
  }
})

// 任意组件中使用
<script>
export default {
  methods: {
    buyGame() {
      this.$store.dispatch('buySomething', 300)
      console.log(`我偷偷花了300块买游戏,家里还剩${this.$store.state.familyMoney}`)
    }
  }
}
</script>

5. provide/inject:跨层级传值

爷爷直接给孙子传家宝,跳过爸爸这一辈!

html 复制代码
<!-- 祖先组件 -->
<script>
export default {
  provide() {
    return {
      familyRelic: '祖传的玉佩'
    }
  }
}
</script>

<!-- 后代组件(任何层级都可以) -->
<script>
export default {
  inject: ['familyRelic'],
  created() {
    console.log(`我继承了${this.familyRelic}`) // 我继承了祖传的玉佩
  }
}
</script>

6. $refs:直接访问组件实例

有时候直接"吼"一声比传纸条快

html 复制代码
<template>
  <child-component ref="child" />
  <button @click="callChild">叫儿子</button>
</template>

<script>
export default {
  methods: {
    callChild() {
      this.$refs.child.sayHello()
      console.log('我直接调用了子组件的方法')
    }
  }
}
</script>

7. <math xmlns="http://www.w3.org/1998/Math/MathML"> a t t r s / attrs/ </math>attrs/listeners:高阶传值技巧

不想一层层传递props?试试这个!

html 复制代码
<!-- 父组件 -->
<child-component :name="myName" :age="30" @click="handleClick" />

<!-- 中间组件 -->
<grand-child v-bind="$attrs" v-on="$listeners" />

<!-- 最终子组件 -->
<script>
export default {
  created() {
    console.log(this.$attrs) // { name: '小杨', age: 30 }
  }
}
</script>

小杨的实战建议

  1. 简单场景:用props和自定义事件就够了
  2. 兄弟通信:小型项目用Event Bus,大型项目直接上Vuex
  3. 跨层级:provide/inject很方便但别滥用
  4. 全局状态:Vuex适合中大型项目,小项目可能杀鸡用牛刀
  5. 直接访问:$refs很方便,但破坏了组件封装性,慎用

记住,没有最好的方式,只有最适合的方式。我在实际项目中经常混合使用这些方法,关键是要保持代码清晰可维护。

最后说两句

组件通信就像人与人之间的交流,方式很多,重要的是选择合适的场景。刚入行时我也经常为传值问题头疼,现在回头看,其实掌握了核心原理就很简单。希望这篇分享能帮你少走弯路!

相关推荐
北凉温华几秒前
Vue 3 + AntV X6 实现流程编辑功能
前端·vue.js
独立开阀者_FwtCoder15 分钟前
从卡顿到丝滑,AI 应用体验跃升的幕后推手是它!
前端·vue.js·面试
知否技术19 分钟前
2025微信小程序开发实战教程(二)
前端·微信小程序
前端小巷子22 分钟前
跨标签页通信(一):BroadcastChannel
前端·面试·浏览器
前端付豪22 分钟前
微信支付风控系统揭秘:交易评分、实时拦截与行为建模全流程实战
前端·后端·架构
uhakadotcom23 分钟前
完了,AI中台比数据中台更短命
面试·架构·github
我有CV两法可开前端一片天24 分钟前
uni-app实现文件上传、下载、预览(非只图片和视频)
前端
BUG收容所所长26 分钟前
揭秘 To-Do List:一个前端小玩具的“幕后玩家”
javascript·css
断竿散人27 分钟前
CSS布局完全指南(下)-Flexbox完全征服指南:一维布局的终极解决方案
前端·css
前端付豪28 分钟前
微信视频号推荐系统揭秘:兴趣建模、多模态分析与亿级流控架构实战
前端·后端·算法