1. defineModel 的多 v-model 绑定(defineModel('a')、defineModel('b'))
defineModel 如何支持多个 v-model 绑定?defineModel('a') 与 defineModel('b') 的机制与工程价值是什么?
- defineModel() 编译为 modelValue prop + update:modelValue emit 的简写
- 命名 v-model(defineModel('a'))对应 a prop 与 update:a emit
- 双向绑定语法糖在子组件内的简化与类型安全
defineModel 是 Vue 3.4 引入的编译宏,把"声明 prop + 声明 emit + 读写 ref"三件事压缩为一个响应式 ref:默认的 defineModel() 对应父组件 v-model 的 modelValue prop 与 update:modelValue 事件;defineModel('a')、defineModel('b') 则声明命名模型,分别对应 v-model:a、v-model:b 的绑定,编译为 a/b prop 与 update:a/update:b emit。子组件内部直接读写该 ref(如 value.value = x),赋值会自动触发对应的 update 事件通知父组件,实现真正的双向绑定且天然类型安全——prop 类型与"是否必填、默认值"可通过 defineModel 的参数配置。多个命名模型让一个组件同时受控多个维度(如分页组件的 page 与 pageSize),避免为每个维度手写 prop/emit 样板代码。
理解 defineModel 的关键是"编译宏 + 语法糖":它没有新增运行时机制,只是把既有 prop/emit 模式自动化,并让"子组件内读写如 ref"的体验与单向数据流原则兼容(对 ref 赋值本质是派发 update 事件)。回答时建议强调"默认模型 vs 命名模型"的对应关系,以及可选的 required/default/type 配置,说明其对组件库 API 设计的简化价值。
<!-- 子组件 -->
<script setup>
const page = defineModel('page', { type: Number, required: true })
const pageSize = defineModel('pageSize', { type: Number, default: 20 })
</script>
<!-- 父组件:<Pagination v-model:page="p" v-model:page-size="size" /> -->