Vue 3 中使用 v-model 实现父子组件间状态双向绑定的完整教程

1次阅读

Vue 3 中使用 v-model 实现父子组件间状态双向绑定的完整教程

本文详解如何在 vue 3 组合式 API 中,通过 v-model 将父组件中的响应式状态(如 user.favoriteColor)双向绑定到可复用的 子组件,实现选中值自动同步与更新。

本文详解如何在 vue 3 组合式 api 中,通过 `v-model` 将父组件中的响应式状态(如 `user.favoritecolor`)双向绑定到可复用的 `` 子组件,实现选中值自动同步与更新。

在 Vue 3 中,v-model 不再是语法糖的简单替代,而是基于 modelValue prop 和 update:modelValue 事件的标准化双向绑定机制。它为自定义表单组件(如 )提供了清晰、一致且符合 Vue 生态约定的通信方式。

要将 Home.vue 中 user.favoriteColor 的状态与 同步,关键在于两步协同:父组件使用 v-model 传递绑定值子组件接收并主动触发更新事件

✅ 父组件:声明式绑定(简洁直观)

在 Home.vue 中,无需手动监听事件或编写额外逻辑,直接使用 v-model 指向目标响应式字段:

<!-- Home.vue --> <script setup> import { ref } from 'vue' import selectinput from './SelectInput.vue'  const user = ref({   name: '',   favoriteColor: '' // 初始为空字符串,与 select 的空选项 value 一致 })  const selectOptions = ref(['red', 'green', 'blue', 'white', 'black']) </script>  <template>   <div class="user-input-container">     <div class="user-input">       <p>Favorite Color</p><p><span>立即学习</span>“<a href="https://pan.quark.cn/s/cb6835dc7db1" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">前端免费学习笔记(深入)</a>”;</p><div class="aritcle_card flexRow">                                                         <div class="artcardd flexRow">                                                                 <a class="aritcle_card_img" href="/ai/963" title="文赋Ai论文"><img                                                                                 src="https://img.php.cn/upload/ai_manual/000/000/000/175680173162717.png" alt="文赋Ai论文"  onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>                                                                 <div class="aritcle_card_info flexColumn">                                                                         <a href="/ai/963" title="文赋Ai论文">文赋Ai论文</a>                                                                         <p>专业/高质量智能论文AI生成器-在线快速生成论文初稿</p>                                                                 </div>                                                                 <a href="/ai/963" title="文赋Ai论文" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a>                                                         </div>                                                 </div>       <!-- ✅ 使用 v-model 直接绑定嵌套属性 -->       <SelectInput v-model="user.favoriteColor" :options="selectOptions" />     </div>   </div> </template>

? 注意:我们同时传入了 :options(原 :selectOptions),用于保持选项数据流清晰——v-model 专责值绑定,options 专责渲染配置。

✅ 子组件:合规实现 v-model 协议

SelectInput.vue 需遵循 Vue 3 的 v-model 默认约定:

  • 接收名为 modelValue 的 prop(类型需与绑定值匹配,此处为 String);
  • 通过 defineEmits 声明 update:modelValue 事件;
<!-- SelectInput.vue --> <script setup> import { defineProps, defineEmits } from 'vue'  // ✅ 接收 v-model 绑定的值(默认 modelValue) const props = defineProps({   modelValue: {     type: String,     default: ''   },   options: {     type: Array,     required: true,     default: () => []   } })  // ✅ 声明更新事件 const emit = defineEmits(['update:modelValue'])  // ✅ 处理选择变更 const handleChange = (e) => {   emit('update:modelValue', e.target.value) } </script>  <template>   <select      :value="modelValue"      @change="handleChange"     class="select-input"   >     <option disabled value="">Please select one</option>     <option        v-for="option in options"        :key="option"        :value="option"     >       {{ option }}     </option>   </select> </template>  <style scoped> .select-input {   padding: 0.5rem;   border: 1px solid #ccc;   border-radius: 4px;   font-size: 1rem; } </style>

⚠️ 重要细节:

  • :value 必须显式绑定 modelValue,否则原生
  • @change 是语义最准确的事件(比 @input 更符合表单提交场景);
  • :key 和 :value 均需正确设置,避免选项错乱或值不更新。

✅ 进阶:支持自定义 v-model 修饰符(可选)

若需支持如 v-model.trim 或自定义修饰符(例如 v-model.number),可在子组件中扩展 defineProps 和事件逻辑。但对字符串选择器而言,标准实现已完全满足需求。

✅ 总结:最佳实践要点

  • 命名规范:始终使用 modelValue + update:modelValue,避免自定义事件名(如 change)导致 v-model 失效;
  • 类型安全:为 modelValue 明确指定 type(如 String、Number、Array),提升可维护性;
  • 空值处理:确保初始 modelValue 与
  • 复用性保障:将数据(options)与状态(modelValue)分离传递,使组件真正可配置、可测试、可组合。

通过这套标准化模式, 不仅能绑定 user.favoriteColor,还可无缝用于 user.country、form.status 等任意字符串字段,真正成为可靠、可维护的 UI 基础组件。

text=ZqhQzanResources