🔁 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
(不推薦頻繁使用)