vue如何实现组件通信
父子组件通信
父组件通过 props 向子组件传递数据,子组件通过 $emit 触发事件向父组件传递数据。父组件可以在模板中使用 v-bind 绑定 props,子组件通过 props 选项接收数据。
<!-- 父组件 -->
<template>
<child-component :message="parentMessage" @update="handleUpdate" />
</template>
<script>
export default {
data() {
return {
parentMessage: 'Hello from parent'
}
},
methods: {
handleUpdate(newMessage) {
this.parentMessage = newMessage
}
}
}
</script>
<!-- 子组件 -->
<template>
<div>
<p>{{ message }}</p>
<button @click="notifyParent">Update Parent</button>
</div>
</template>
<script>
export default {
props: ['message'],
methods: {
notifyParent() {
this.$emit('update', 'Updated message from child')
}
}
}
</script>
兄弟组件通信
通过共同的父组件作为中介实现兄弟组件通信。一个子组件通过 $emit 触发事件,父组件监听事件并更新数据,另一个子组件通过 props 接收更新后的数据。
<!-- 父组件 -->
<template>
<child-a @update="handleUpdate" />
<child-b :message="sharedMessage" />
</template>
<script>
export default {
data() {
return {
sharedMessage: ''
}
},
methods: {
handleUpdate(message) {
this.sharedMessage = message
}
}
}
</script>
跨层级组件通信
使用 provide 和 inject 实现祖先组件向后代组件传递数据。祖先组件通过 provide 提供数据,后代组件通过 inject 注入数据。
// 祖先组件
export default {
provide() {
return {
theme: 'dark'
}
}
}
// 后代组件
export default {
inject: ['theme'],
created() {
console.log(this.theme) // 输出 'dark'
}
}
全局事件总线
创建一个空的 Vue 实例作为事件总线,实现任意组件间的通信。组件通过 $on 监听事件,通过 $emit 触发事件。
// event-bus.js
import Vue from 'vue'
export const EventBus = new Vue()
// 组件A
EventBus.$emit('event-name', data)
// 组件B
EventBus.$on('event-name', data => {
console.log(data)
})
Vuex 状态管理
对于复杂的应用,使用 Vuex 集中管理状态。组件通过 mapState、mapGetters、mapMutations 和 mapActions 与 Vuex 交互。
// store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++
}
}
})
// 组件
export default {
computed: {
...mapState(['count'])
},
methods: {
...mapMutations(['increment'])
}
}
$attrs 和 $listeners
$attrs 包含父组件传递的非 props 属性,$listeners 包含父组件传递的事件监听器。可以通过 v-bind="$attrs" 和 v-on="$listeners" 向下传递。
<!-- 父组件 -->
<child-component :title="title" @custom-event="handleEvent" />
<!-- 中间组件 -->
<template>
<grand-child v-bind="$attrs" v-on="$listeners" />
</template>
$parent 和 $children
通过 $parent 访问父组件实例,通过 $children 访问子组件实例。这种方式直接操作组件实例,可能导致代码难以维护,应谨慎使用。
// 子组件访问父组件
this.$parent.someMethod()
// 父组件访问子组件
this.$children[0].someMethod()






