defineModel
是 Vue 3.4 及以上版本中引入的 Composition API 宏指令,用于简化父子组件间的双向数据绑定,通过声明式语法替代传统 props
+ emit
模式,显著提升代码可维护性和开发效率。
<!-- 子组件 -->
<template>
<input v-model="email">
</template>
<script setup>
const userName = defineModel('userName');
const email = defineModel('email', {
type: String,
default: '初始值',
required: true
})
</script>
<!-- 父组件 -->
<Child v-model:userName="user" v-model:email="mail" ></Child>`
实现原理
defineModel
实际上是在子组件内定义了一个 ref
变量和对应的 modelValue
属性,并监听了对应的属性。当 props
中的 modelValue
的值改变后,会同步更新 ref
变量的值;当在子组件内改变 ref
变量的值后,会抛出 update:modelValue
事件,父组件收到这个事件后就会更新对应的变量值,从而实现双向绑定。
注意事项
defineModel
是一个宏,所以不需要从 Vue
中导入,直接使用即可。
在 TypeScript
中使用 defineModel
时,可以提供类型推导支持,例如 defineModel<string>()
。
defineModel
的返回值是一个 ref
,在子组件中可以直接对这个 ref
对象进行赋值,父组件内的相应变量也会同步修改。