Vue 3 中父子组件双向绑定的 4 种方式
🔁 Vue 3 中父子组件双向绑定的 4 种方式
整理不易,点赞 + 收藏 + 关注,助你组件通信不再混乱!
✅ 场景说明
- 父组件希望将某个值传递给子组件,同时希望子组件能够修改这个值(实现“绑定 + 反向更新”)。
- 类似于 v-model 的使用效果。
🧩 方式一:使用 v-model
+ modelValue
+ emit("update:modelValue")
✅ 推荐:官方支持、语义清晰、适用于表单类组件
子组件写法:
<!-- components/MyInput.vue -->
<template><input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" />
</template><script setup>
defineProps({modelValue: String
})
defineEmits(['update:modelValue'])
</script>
父组件用法:
<MyInput v-model="username" />
🧩 方式二:自定义 v-model:xxx
实现多个绑定值
✅ 多值绑定场景适用,例如表单组件同时绑定 value
和 checked
子组件:
<template><input:value="modelValue":checked="checked"@input="$emit('update:modelValue', $event.target.value)"@change="$emit('update:checked', $event.target.checked)"/>
</template><script setup>
defineProps(['modelValue', 'checked'])
defineEmits(['update:modelValue', 'update:checked'])
</script>
父组件:
<MyInput v-model:modelValue="text" v-model:checked="isChecked" />
🧩 方式三:使用 v-bind
+ @update
+ defineModel
(Vue 3.3+)
⚠️ 仅支持 Vue 3.3 及以上版本!
子组件:
<script setup>
const model = defineModel<string>() // 等价于 props + emit
</script><template><input :value="model" @input="model = $event.target.value" />
</template>
父组件:
<MyInput v-model="msg" />
✔️ 不用显式声明 props 和 emits,推荐新项目使用!
🧩 方式四:手动通过 props + emit 自定义字段实现绑定
✅ 适合非表单类组件 / 业务交互逻辑强的组件
子组件:
<template><button @click="toggle">{{ active ? 'ON' : 'OFF' }}</button>
</template><script setup>
const props = defineProps({ active: Boolean })
const emit = defineEmits(['update:active'])const toggle = () => {emit('update:active', !props.active)
}
</script>
父组件:
<MyToggle v-model:active="isActive" />
🧠 小结对比表
方式 | 特点 | 场景建议 |
---|---|---|
v-model + modelValue | 最常用,官方推荐 | 表单组件 |
v-model:xxx 多 model | 绑定多个值 | 复合组件(如 input + checked) |
defineModel() | Vue 3.3+ 自动绑定 | 新项目、轻量双绑组件 |
props + emit 自定义字段 | 自定义灵活 | 任意双向控制场景 |
✅ 补充:实现“子改父”但不一定是“绑定”
- 子组件调用函数修改父组件数据:
<!-- 父组件 -->
<MyChild :value="count" @change="count = $event" /><!-- 子组件 -->
$emit('change', newValue)
- 父传
ref
,子组件直接修改ref.value
(不推荐频繁使用)