v-model 在 Vue 3 中通过 :modelValue 和 @update:modelValue 实现模态框开关状态的父子同步,子组件触发 emit('update:modelValue', false) 请求关闭,父组件响应更新;支持自定义参数名实现多状态解耦。

v-model 在 Vue 3 中处理模态框的打开与关闭,本质是利用其语法糖机制实现父子组件间的状态同步:父组件传入一个布尔值(默认对应 modelValue prop),子组件在需要关闭时触发 update:modelValue 事件通知父组件更新。这种方式简洁、语义清晰,且与 Element Plus 等主流 UI 库原生兼容。
核心原理:v-model 是 props + emit 的组合
当在模态框组件上写 <MyModal v-model="show"> 时,Vue 3 实际将其编译为:
- 向子组件传递
:modelValue="show" - 监听子组件发出的
@update:modelValue事件,并自动更新show值
子组件不能直接修改 modelValue(props 不可变),而是通过 emit('update:modelValue', false) 主动“请求关闭”,由父组件决定是否响应。
子组件中正确接收和响应
子组件需显式声明 modelValue prop 和 update:modelValue 事件:
立即学习“前端免费学习笔记(深入)”;
- 使用
defineProps(['modelValue'])或defineProps<{ modelValue: boolean }>() - 使用
defineEmits(['update:modelValue']) - 关闭逻辑(如点击 ×、遮罩层、取消按钮)统一调用
emit('update:modelValue', false) - 注意:不要在
<el-dialog>内直接用v-model="modelValue",应改用:model-value="modelValue"配合@close或@closed触发 emit,避免内部双向绑定冲突
父组件调用示例(含常见交互)
父组件只需维护一个响应式布尔值,无需额外方法:
const show = ref(false)- 打开:按钮点击设为
true,例如@click="show = true" - 关闭:由子组件 emit 触发自动更新,也可手动设为
false - 支持链式操作,如
<MyModal v-model="show" @update:modelValue="onModalChange">,在onModalChange中做副作用处理
进阶:支持多个 v-model(如同时控制显隐 + 标题)
若需解耦不同状态,可自定义参数名:
- 父组件:
<MyModal v-model:visible="show" v-model:title="modalTitle"> - 子组件:
defineProps({ visible: Boolean, title: String }),并defineEmits(['update:visible', 'update:title']) - 这样标题变更和开关状态互不影响,适合复杂弹窗场景


















