Vue 学院 #5:组件之间的通信

2025-06-04

Vue 学院 #5:组件之间的通信

当你将道具从父级传递给子级时,你可能需要更新这些数据。

在 Vuejs 中,有两种方法可以处理这种情况,最常用的是emit从子组件向父组件发送事件。另一种方法是使用bus event

从子级发出事件

在组件范例中,我们在组件中的组件中有一个组件...您可以从一个父组件向另一个子组件传递多个数据,称为props

在某些情况下,您需要从其中一个子组件来更新这些道具!

你应该直接更新这些道具吗?

如果你尝试在 props 对象上执行此操作,Vue 将触发warn关于此操作的错误。千万不要这么做

⚠️ 像这样改变 props 被认为是一种反模式!

两条规则:

  • 只有组件可以改变其状态

  • 只有组件的父级可以更改 props

那么如何才能正确地更新来自孩子的道具呢?!

使用emit event

1)从子组件发出一个具有新值的事件,以更新此事件中的道具。

2)在父级中处理此事件并更新数据!

一个简短的例子👇

上下文:我们需要在点击时更新 props

Child.vue

<template>
<div>
     <!-- When we click on button, we want to update value -->
    <button @click="updateCounter(counter + 1)">
</div>
</template>
<script>
import Vue from "vue"

export default Vue.extend({
    props: {
        counter: Number,
    },
    methods: {
       updateCounter(newValue) {
         // 1) Emit event from child with the new value
         this.$emit('update-counter', newValue)
       }
    }
})
</script>
Enter fullscreen mode Exit fullscreen mode

父级.vue

<template>
<div>
    <child
       :counter="counter"
       <!-- 2) We handle the update event and we update the current props value ! -->
       @update-counter="counter = $event"
       />
</div>
</template>
<script>
import Vue from "vue"
// We omit Child component import

export default Vue.extend({
    components: {
       Child,
    },
    data() {
        return {
            counter: 0,
        }
    },
})
</script>
Enter fullscreen mode Exit fullscreen mode

如你所见,从子级更新 props 值非常简单!如果你有更多像这样的深层子级 👇

父母 -> 孩子一 -> 孩子二

孩子二有两个父母,父母和孩子一。

如果您需要Child two更新道具,您可以向Child One发出一个事件,并向Parent发出另一个事件!

一般来说,这个技巧是有效的,但在某些情况下,您需要从一个组件向另一个未通过父级链接的组件进行通信,例如,假设您的 Footer 需要与您的 Header 进行通信。

不能在它们之间发出事件!

如何处理这个问题?

巴士活动

Vue 允许我们使用总线事件!

这是一种无需使用Parent即可在两个组件之间发出数据的方法

首先,我们需要创建我们的巴士活动!

import Vue from 'vue'
import App from './App.vue'


export const bus = new Vue()

new Vue({
  render: h => h(App),
}).$mount('#app')
Enter fullscreen mode Exit fullscreen mode

页脚.vue

<script>
import Vue from "vue"
// We omit template and bus import

export default Vue.extend({
    methods {
        emitValueWithBus(value) {
           // Emit value thanks to the bus
           bus.$emit('update-value', 'toto')
        }
    },
})
</script>
Enter fullscreen mode Exit fullscreen mode

Header.vue

<script>
import Vue from "vue"
// We omit template and bus import

export default Vue.extend({
   // Init the bus connection when created component
   created () {
       // Get value from event with the bus event
       bus.$on('update-value', (data) => {
          // data is equal to 'toto' !
       })
   },
   destroyed() {
      // When component is destroyed we should remove listener
      bus.$off()
   }
})
</script>
Enter fullscreen mode Exit fullscreen mode

📝注意:我们手动删除监听器,Vue 会自动处理这种情况的巴士事件

结论

正如我们之前看到的,如果您需要更新 props 值,则需要在父组件中处理它event

但在某些情况下我们不能使用这些技巧,所以我们需要使用event bus


我希望你喜欢这篇文章!

🎁 如果您在TwitterUnderrated skills in javascript, make the difference上关注我并给我点赞,即可免费获得我的新书😁

或者在这里获取

🎁我的新闻通讯

☕️ 你可以支持我的作品🙏

🏃‍♂️ 你可以关注我 👇

🕊 推特:https://twitter.com/code__oz

👨‍💻 Github:https://github.com/Code-Oz

你也可以标记🔖这篇文章!

文章来源:https://dev.to/codeoz/vue-academy-5-communication- Between-components-4d53
PREV
Webpack 学院 #0:什么是 webpack 以及为什么使用它?
NEXT
Vue 学院 #1:作用域样式