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

相关推荐
ZC跨境爬虫1 小时前
跟着 MDN 学 HTML day_9:(信件语义标记)
前端·css·笔记·ui·html
前端老石人2 小时前
HTML 字符引用完全指南
开发语言·前端·html
幼儿园技术家2 小时前
前端如何设计权限系统(RBAC / ABAC)?
前端
前端摸鱼匠4 小时前
Vue 3 的v-bind合并行为:讲解v-bind与普通属性合并的规则
前端·javascript·vue.js·前端框架·ecmascript
REDcker4 小时前
浏览器端Web程序性能分析与优化实战 DevTools指标与工程清单
开发语言·前端·javascript·vue·ecmascript·php·js
donecoding5 小时前
一个 sudo 引发的血案:npm 全局包权限错乱彻底修复
前端·node.js·前端工程化
风骏时光牛马6 小时前
Raku正则匹配与数据批量处理实操案例
前端
nbwenren6 小时前
2026实测:Gemini 3 镜像站视觉能力实践——拍照原型图,一键生成 HTML+CSS 代码
前端·css·html
Lee川6 小时前
Prisma 实战指南:像搭积木一样设计古诗词数据库
前端·数据库·后端