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

相关推荐
前端小端长10 分钟前
qiankun 微前端应用入门教程:从搭建到部署
前端
yinuo2 小时前
前端跨页面通讯终极指南⑥:SharedWorker 用法全解析
前端
PineappleCoder7 小时前
还在重复下载资源?HTTP 缓存让二次访问 “零请求”,用户体验翻倍
前端·性能优化
拉不动的猪7 小时前
webpack编译中为什么不建议load替换ast中节点删除consolg.log
前端·javascript·webpack
李姆斯7 小时前
Agent时代下,ToB前端的UI和交互会往哪走?
前端·agent·交互设计
源码获取_wx:Fegn08957 小时前
基于springboot + vue健身房管理系统
java·开发语言·前端·vue.js·spring boot·后端·spring
闲谈共视7 小时前
基于去中心化社交与AI智能服务的Web钱包商业开发的可行性
前端·人工智能·去中心化·区块链
CreasyChan8 小时前
C# 反射详解
开发语言·前端·windows·unity·c#·游戏开发
JIngJaneIL8 小时前
基于Java+ vue智慧医药系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot
+VX:Fegn08958 小时前
计算机毕业设计|基于springboot + vue图书管理系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计