vue3.3 defineModel

Vue 3.3新增了 defineModel ,他是一个新的编译器宏,主要用于简化组件中 v-model 的双向绑定声明,尤其在 <script setup> 语法中。


一、defineModel 的核心作用

defineModel 旨在简化父子组件间的双向数据绑定,替代传统手动声明 propsemit 的繁琐流程。它自动处理以下内容:

  1. 声明 Prop :自动生成与 v-model 绑定的 prop
  2. 触发事件 :修改值时自动触发 update:modelValue 事件。
  3. 类型推断:支持 TypeScript 类型推断,无需额外类型声明。

二、基本用法

1. 默认 v-model 绑定

在子组件中直接使用 defineModel() 声明默认的 v-model 绑定:

vue 复制代码
<!-- 子组件 Child.vue -->
<script setup>
const modelValue = defineModel()
</script>

<template>
  <input 
    :value="modelValue"
    @input="e => modelValue = e.target.value"
  />
</template>

父组件使用 v-model 绑定数据:

vue 复制代码
<!-- 父组件 Parent.vue -->
<template>
  <Child v-model="message" />
</template>

2. 带参数的 v-model(多绑定)

支持多个 v-model 绑定,例如 v-model:titlev-model:content

vue 复制代码
<!-- 子组件 Child.vue -->
<script setup>
const title = defineModel('title')
const content = defineModel('content')
</script>

<template>
  <input :value="title" @input="e => title = e.target.value" />
  <textarea :value="content" @input="e => content = e.target.value" />
</template>

父组件传递多个绑定:

vue 复制代码
<!-- 父组件 Parent.vue -->
<template>
  <Child 
    v-model:title="pageTitle"
    v-model:content="pageContent"
  />
</template>

三、高级配置

1. 设置默认值

通过传递选项对象为 defineModel 设置默认值:

javascript 复制代码
const modelValue = defineModel({ default: '初始值' })

2. 类型验证

结合 TypeScript 进行类型校验:

typescript 复制代码
const modelValue = defineModel<string>({ required: true })

3. 自定义修饰符

处理 v-model 修饰符(如 .trim):

vue 复制代码
<!-- 父组件 -->
<Child v-model.trim="text" />

<!-- 子组件 -->
<script setup>
const modelValue = defineModel({
  set(value) {
    // 应用修饰符逻辑(如 trim)
    return value.trim()
  }
})
</script>

四、与传统方式的对比

1. 传统方式(显式 props + emit

vue 复制代码
<script setup>
const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])

function handleInput(e) {
  emit('update:modelValue', e.target.value)
}
</script>

<template>
  <input :value="modelValue" @input="handleInput" />
</template>

2. 使用 defineModel 简化

vue 复制代码
<script setup>
const modelValue = defineModel()
</script>

<template>
  <input :value="modelValue" @input="e => modelValue = e.target.value" />
</template>

优势:减少样板代码,提升可读性,自动处理事件触发。


五、注意事项

  1. 仅限 <script setup>
    defineModel 是编译器宏,仅在 <script setup> 中可用。

  2. 版本兼容性

    需 Vue 3.3+ 支持,确保项目依赖版本正确。

  3. 避免与手动 props 冲突

    不要手动声明与 defineModel 同名的 props,否则会导致覆盖或冲突。

  4. 复杂逻辑需回退传统方式

    如需自定义事件名或复杂校验逻辑,仍需使用 defineProps + defineEmits

  5. 修饰符处理

    若父组件使用修饰符(如 .lazy),需在子组件中显式实现其逻辑。


六、总结

  • 简化双向绑定defineModel 大幅减少 v-model 的声明代码。
  • 多绑定支持 :轻松处理多个 v-model 参数(如 v-model:title)。
  • 类型安全:天然支持 TypeScript 类型推断。
  • 适用场景:推荐在简单双向绑定场景中使用,复杂场景可结合传统方式。

现在,使用 defineModel,可以显著提升 Vue 3 组件的开发效率和代码可维护性。

相关推荐
崔庆才丨静觅4 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60615 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了5 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅5 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅6 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅6 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment6 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅6 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊6 小时前
jwt介绍
前端
爱敲代码的小鱼7 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax