vue父子实现
Vue 父子组件通信实现
Vue 中父子组件通信主要通过 props 和 events 实现。父组件通过 props 向子组件传递数据,子组件通过 events 向父组件发送消息。
父组件向子组件传递数据
父组件通过 props 向子组件传递数据。子组件需要在 props 选项中声明接收的属性。
<!-- 父组件 -->
<template>
<child-component :message="parentMessage"></child-component>
</template>
<script>
import ChildComponent from './ChildComponent.vue'
export default {
components: {
ChildComponent
},
data() {
return {
parentMessage: 'Hello from parent'
}
}
}
</script>
<!-- 子组件 -->
<template>
<div>{{ message }}</div>
</template>
<script>
export default {
props: {
message: {
type: String,
required: true
}
}
}
</script>
子组件向父组件传递数据
子组件通过 $emit 触发事件向父组件传递数据。父组件通过 v-on 监听子组件触发的事件。
<!-- 子组件 -->
<template>
<button @click="sendMessage">Send Message</button>
</template>
<script>
export default {
methods: {
sendMessage() {
this.$emit('message-sent', 'Hello from child')
}
}
}
</script>
<!-- 父组件 -->
<template>
<child-component @message-sent="handleMessage"></child-component>
</template>
<script>
import ChildComponent from './ChildComponent.vue'
export default {
components: {
ChildComponent
},
methods: {
handleMessage(message) {
console.log(message) // 输出: Hello from child
}
}
}
</script>
使用 v-model 实现双向绑定
v-model 是 Vue 提供的语法糖,用于在组件上实现双向绑定。子组件需要接收 value prop 并触发 input 事件。

<!-- 父组件 -->
<template>
<child-component v-model="message"></child-component>
</template>
<script>
import ChildComponent from './ChildComponent.vue'
export default {
components: {
ChildComponent
},
data() {
return {
message: ''
}
}
}
</script>
<!-- 子组件 -->
<template>
<input :value="value" @input="$emit('input', $event.target.value)">
</template>
<script>
export default {
props: {
value: {
type: String,
required: true
}
}
}
</script>
使用 .sync 修饰符
.sync 修饰符是另一种实现父子组件双向绑定的方式。子组件需要触发 update:propName 事件。
<!-- 父组件 -->
<template>
<child-component :message.sync="parentMessage"></child-component>
</template>
<script>
import ChildComponent from './ChildComponent.vue'
export default {
components: {
ChildComponent
},
data() {
return {
parentMessage: ''
}
}
}
</script>
<!-- 子组件 -->
<template>
<input :value="message" @input="$emit('update:message', $event.target.value)">
</template>
<script>
export default {
props: {
message: {
type: String,
required: true
}
}
}
</script>
使用 $refs 访问子组件
父组件可以通过 $refs 直接访问子组件的属性和方法。

<!-- 父组件 -->
<template>
<child-component ref="child"></child-component>
<button @click="callChildMethod">Call Child Method</button>
</template>
<script>
import ChildComponent from './ChildComponent.vue'
export default {
components: {
ChildComponent
},
methods: {
callChildMethod() {
this.$refs.child.childMethod()
}
}
}
</script>
<!-- 子组件 -->
<template>
<div>Child Component</div>
</template>
<script>
export default {
methods: {
childMethod() {
console.log('Child method called')
}
}
}
</script>
使用 provide/inject
provide/inject 允许祖先组件向所有子孙组件注入依赖,适用于深层嵌套组件通信。
<!-- 祖先组件 -->
<template>
<child-component></child-component>
</template>
<script>
import ChildComponent from './ChildComponent.vue'
export default {
components: {
ChildComponent
},
provide() {
return {
ancestorMessage: 'Message from ancestor'
}
}
}
</script>
<!-- 子孙组件 -->
<template>
<div>{{ message }}</div>
</template>
<script>
export default {
inject: ['ancestorMessage'],
data() {
return {
message: this.ancestorMessage
}
}
}
</script>
使用事件总线
对于非父子关系的组件通信,可以使用事件总线(Event Bus)模式。
// event-bus.js
import Vue from 'vue'
export const EventBus = new Vue()
<!-- 发送事件的组件 -->
<script>
import { EventBus } from './event-bus.js'
export default {
methods: {
sendMessage() {
EventBus.$emit('message-sent', 'Hello from component')
}
}
}
</script>
<!-- 接收事件的组件 -->
<script>
import { EventBus } from './event-bus.js'
export default {
created() {
EventBus.$on('message-sent', message => {
console.log(message)
})
}
}
</script>
使用 Vuex 状态管理
对于复杂应用,建议使用 Vuex 进行状态管理,实现组件间的数据共享。
// store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
message: ''
},
mutations: {
setMessage(state, message) {
state.message = message
}
},
actions: {
updateMessage({ commit }, message) {
commit('setMessage', message)
}
}
})
<!-- 组件A -->
<template>
<button @click="updateMessage">Update Message</button>
</template>
<script>
import { mapActions } from 'vuex'
export default {
methods: {
...mapActions(['updateMessage'])
}
}
</script>
<!-- 组件B -->
<template>
<div>{{ message }}</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
computed: {
...mapState(['message'])
}
}
</script>






