vue父子实现
Vue 父子组件通信实现
Vue 中父子组件通信主要通过 props 和自定义事件实现。父组件向子组件传递数据使用 props,子组件向父组件传递数据使用自定义事件。
父组件向子组件传递数据
父组件通过 props 向子组件传递数据。子组件需要在 props 选项中声明接收的属性。
父组件模板:
<template>
<child-component :message="parentMessage" />
</template>
父组件脚本:
<script>
import ChildComponent from './ChildComponent.vue'
export default {
components: {
ChildComponent
},
data() {
return {
parentMessage: 'Hello from parent'
}
}
}
</script>
子组件脚本:
<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-from-child', 'Hello from child')
}
}
}
</script>
父组件模板:
<template>
<child-component @message-from-child="handleChildMessage" />
</template>
父组件脚本:
<script>
import ChildComponent from './ChildComponent.vue'
export default {
components: {
ChildComponent
},
methods: {
handleChildMessage(message) {
console.log(message) // 输出: 'Hello from child'
}
}
}
</script>
使用 v-model 实现双向绑定
对于表单元素等需要双向绑定的场景,可以使用 v-model 简化父子组件通信。

子组件需要接收 value prop 并触发 input 事件:
子组件模板:
<template>
<input :value="value" @input="$emit('input', $event.target.value)" />
</template>
子组件脚本:
<script>
export default {
props: {
value: {
type: String,
required: true
}
}
}
</script>
父组件使用:
<template>
<child-component v-model="parentValue" />
</template>
使用 .sync 修饰符
Vue 2.x 中可以使用 .sync 修饰符实现父子组件双向绑定。
子组件触发 update:propName 事件:

this.$emit('update:title', newTitle)
父组件使用:
<child-component :title.sync="parentTitle" />
访问子组件实例
父组件可以通过 ref 直接访问子组件实例:
父组件模板:
<template>
<child-component ref="child" />
</template>
父组件脚本:
<script>
export default {
methods: {
callChildMethod() {
this.$refs.child.childMethod()
}
}
}
</script>
插槽通信
通过作用域插槽可以实现父组件访问子组件数据:
子组件模板:
<template>
<div>
<slot :user="user"></slot>
</div>
</template>
父组件使用:
<template>
<child-component>
<template v-slot:default="slotProps">
{{ slotProps.user.name }}
</template>
</child-component>
</template>






