🔥 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很方便,但破坏了组件封装性,慎用

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

最后说两句

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

相关推荐
ONE_Gua几秒前
Wireshark常用过滤规则
前端·后端·数据挖掘
enki081511 分钟前
【CANN训练营】+开源之星+GitCode算子开发环境快速搭建手册
javascript·ecmascript·jquery
通往曙光的路上15 分钟前
vue啊哈哈哈哈哈哈哈哈
前端·javascript·vue.js
fouryears_2341719 分钟前
如何将Vue 项目转换为 Android App(使用Capacitor)
android·前端·vue.js
葡萄城技术团队23 分钟前
在线Excel新突破:SpreadJS如何完美驾驭中国式复杂报表
前端
muchan9225 分钟前
这会不会引起编程范式的变革?
前端·后端·编程语言
进阶的鱼30 分钟前
React+ts+vite脚手架搭建(四)【mock篇】
前端·javascript·react.js
Jagger_34 分钟前
Scrum敏捷开发流程规范
前端·后端
Value_Think_Power36 分钟前
变量->约束->目标
前端
开源框架37 分钟前
招商银行模拟器app,网银模拟生成器,jar+c++组合模板
前端