defineModel 一行代码替代 props + emits + computed,支持默认 modelValue 绑定、自定义多 v-model 字段、TS 类型与默认值、get/set 转换逻辑,是 Vue 编译器级语法糖。

直接用 defineModel 替代手动声明 props + emits + computed,一行代码就能拿到可读可写的响应式变量,父组件照常用 v-model,子组件内部像操作本地 ref 一样使用。
基础用法:默认 modelValue 绑定
适用于最常见场景——单个 v-model 绑定,比如输入框、开关等:
- 子组件中写
const model = defineModel(),它自动对应modelValueprop 和update:modelValue事件 - 模板里直接
<input v-model="model" />,无需解构 props 或手写事件处理器 - 父组件仍用
<MyInput v-model="text" />,完全兼容旧写法
自定义名称:支持多 v-model
当组件需要多个双向绑定字段(如表单控件同时控制值、禁用状态、校验结果)时:
- 用字符串参数指定字段名:
const count = defineModel('count') - 对应父组件写法:
<Counter v-model:count="num" /> - 可同时声明多个:
const value = defineModel()、const disabled = defineModel('disabled')
类型与默认值:TypeScript 友好
在 <script setup lang="ts"> 中,defineModel 支持完整类型推导和运行时校验:
立即学习“前端免费学习笔记(深入)”;
- 带类型:
const price = defineModel<number>()</number> - 带默认值:
const active = defineModel<boolean>({ default: true })</boolean> - 两者结合:
const name = defineModel<string>({ default: 'Guest' })</string>
进阶控制:get/set 转换逻辑
需要格式化显示或转换输入值时(如金额、日期、大小写),推荐搭配 computed 使用:
- 定义 model:
const value = defineModel<string>()</string> - 创建计算属性封装转换:
const displayValue = computed({ get: () => value.value.toUpperCase(), set: v => value.value = v.toLowerCase() }) - 模板中绑定计算属性:
<input v-model="displayValue" />
不需要引入额外依赖,不改变调用方式,也不影响响应式系统——defineModel 是 Vue 编译器层面的语法糖,干净、安全、开箱即用。


















