v-model父子通信
时间: 2025-03-15 13:05:48 浏览: 37
### Vue.js 中 `v-model` 实现父子组件通信的方式
#### 1. 基本原理
`v-model` 是 Vue 提供的一种语法糖,用于简化父组件向子组件传递数据以及子组件更新父组件数据的过程。其实现机制基于两个核心功能:
- **`:value` 属性**:通过该属性将父组件的数据传递给子组件。
- **`@input` 事件**:子组件通过触发 `input` 事件通知父组件其内部状态的变化。
这种模式使得开发者可以轻松实现父子组件之间的双向绑定[^5]。
---
#### 2. 使用方法
##### (1)父组件模板中的写法
在父组件中使用 `v-model` 绑定一个变量到子组件上时,实际上等价于以下操作:
```html
<child-component :value="parentData" @input="event => parentData = event"></child-component>
```
因此,下面是一个典型的父组件示例:
```javascript
<template>
<div>
<!-- 子组件 -->
<ChildComponent v-model="formData.value" />
<!-- 修改按钮 -->
<button @click="changeVal">点击修改</button>
<!-- 显示当前值 -->
<h3>父组件显示的值: {{ formData.value }}</h3>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: { ChildComponent },
data() {
return {
formData: {
value: '初始值'
}
};
},
methods: {
changeVal() {
this.formData.value = '父组件已更改';
}
}
};
</script>
```
此处的关键在于 `v-model` 将 `formData.value` 的值传递给了子组件,并监听了来自子组件的输入事件[^2]。
---
##### (2)子组件的响应逻辑
为了支持 `v-model`,子组件需要定义一个名为 `value` 的 prop 和一个 `$emit('input')` 方法来通知父组件数据变更的情况:
```javascript
<template>
<div>
<input :value="value" @input="$emit('input', $event.target.value)" />
</div>
</template>
<script>
export default {
props: ['value']
};
</script>
```
在这个例子中,子组件接收了一个由父组件传递过来的 `value` 数据,并在其发生变化时通过 `$emit('input')` 同步回父组件的状态。
---
#### 3. 高级应用——自定义模型名称
默认情况下,`v-model` 使用 `value` 和 `input` 进行交互,但如果希望更灵活地控制行为,则可以通过设置 `model` 属性重新指定这些字段的名字。例如:
```javascript
// 父组件
<ParentModel custom-value="customPropName" @update-custom-value="handleUpdate">
</ParentModel>
// 自定义 model 定义
export default {
model: {
prop: 'customValue',
event: 'updateCustomValue'
},
props: {
customValue: String
},
methods: {
updateValue(newVal) {
this.$emit('updateCustomValue', newVal);
}
}
}
```
这种方式允许我们更加自由地设计 API 接口[^3]。
---
#### 4. 注意事项
- 如果父组件本身也是一个嵌套结构下的子组件而非根实例 (`new Vue`) ,则需要注意上下文中类型的匹配问题 —— 即可能是普通的 JavaScript 对象也可能是特定框架封装后的类实例[^1]。
- 获取的结果始终为单一的对象形式而不是集合类型(如数组)。这有助于保持接口的一致性和可预测性。
---
### 示例总结代码片段
以下是完整的父子组件间通过 `v-model` 实现双向绑定的例子:
```vue
<!-- Parent Component -->
<template>
<div>
<Son v-model="message"/>
<p>{{ message }}</p>
</div>
</template>
<script>
import Son from './Son.vue';
export default {
components: { Son },
data() {
return {
message: 'Hello, world!'
};
}
};
</script>
<!-- Son Component -->
<template>
<input :value="value" @input="$emit('input', $event.target.value)">
</template>
<script>
export default {
props: ['value']
};
</script>
```
---
阅读全文
相关推荐

















