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 组件的开发效率和代码可维护性。

相关推荐
GISer_Jing1 分钟前
React 18的createRoot与render全面对比
前端·react.js·前端框架
我叫汪枫2 分钟前
React Hooks原理深度解析与高级应用模式
前端·react.js·前端框架
我叫汪枫3 分钟前
深入探索React渲染原理与性能优化策略
前端·react.js·性能优化
阿智@1115 分钟前
推荐使用 pnpm 而不是 npm
前端·arcgis·npm
伍哥的传说26 分钟前
QRCode React 完全指南:现代化二维码生成解决方案
前端·javascript·react.js·qrcode.react·react二维码生成·qrcodesvg·qrcodecanvas
IT_陈寒30 分钟前
Vite 5.0 终极优化指南:7个配置技巧让你的构建速度提升200%
前端·人工智能·后端
listhi52034 分钟前
Map对象在JavaScript循环中的使用
开发语言·前端·javascript
小熊学Java35 分钟前
基于 Spring Boot+Vue 的高校竞赛管理平台
vue.js·spring boot·后端
安卓开发者42 分钟前
鸿蒙Next Web组件生命周期详解:从加载到销毁的全流程掌控
前端
我叫汪枫4 小时前
前端物理引擎库推荐 - 让你的网页动起来!
前端