全面剖析Vue3 全新特性 defineModel

 更新时间:2025年08月19日 09:43:49   作者:第七种黄昏  
defineModel是Vue3.4引入的一个编译器宏,用于简化组件双向数据绑定的实现,它是对v-model指令在组件上使用的语法糖,本文给大家介绍Vue3全新特性defineModel的相关知识,感兴趣的朋友一起看看吧

一、defineModel 是什么?

defineModel 是 Vue 3.4 引入的一个编译器宏,用于简化组件双向数据绑定的实现。它是对 v-model 指令在组件上使用的语法糖,让开发者可以更简洁地实现父子组件之间的双向数据同步。

二、核心优势

  • 代码简化:减少样板代码,不再需要手动定义 props 和 emit
  • 类型安全:完美支持 TypeScript 类型推断
  • 功能强大:内置支持修饰符处理
  • 开发体验:更直观的双向绑定实现方式

三、基础用法

3.1 基本实现

子组件实现

<template>
  <div>
    <input 
    type="text"
    :vaule="modelValue"
    @input="e => modelValue = e.target.value"
    >
  </div>
</template>
<script setup>
import { defineModel } from 'vue';
const modelValue = defineModel()
</script>

父组件使用

<script setup  >
import myinput from '@/components/my-input.vue';
import { ref } from 'vue'
const txt = ref('123456')
</script>
<template>
  <div>
    <myinput v-model="txt"></myinput>
    {{ txt }}
  </div>
</template>

3.2 等效的传统实现

在没有 defineModel 时,我们需要这样写:

<script setup>
const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])
</script>
<template>
  <input
    type="text"
    :value="props.modelValue"
    @input="emit('update:modelValue', $event.target.value)"
  >
</template>

四、高级特性

4.1 多 v-model 支持

子组件

<script setup>
const firstName = defineModel('firstName')
const lastName = defineModel('lastName')
</script>
<template>
  <input v-model="firstName">
  <input v-model="lastName">
</template>

父组件

<UserForm
  v-model:first-name="firstName"
  v-model:last-name="lastName"
/>

4.2 类型定义

<script setup lang="ts">
// 带类型的 defineModel
const count = defineModel<number>('count', { default: 0 })
// 复杂类型
interface User {
  name: string
  age: number
}
const user = defineModel<User>('user')
</script>

4.3 修饰符处理

父组件使用修饰符

<MyInput v-model.trim="text" />

子组件处理修饰符

<script setup>
const [modelValue, modifiers] = defineModel({
  // setter 中可以访问 modifiers
  set(value) {
    if (modifiers.trim) {
      return value.trim()
    }
    return value
  }
})
</script>

五、实现原理

defineModel 在编译阶段会被转换为:

  • 一个 modelValue prop
  • 一个 update:modelValue 事件
  • 一个计算属性,提供 getter 和 setter

编译后的代码类似于:

const props = defineProps({
  modelValue: { type: String }
})
const emit = defineEmits(['update:modelValue'])
const modelValue = computed({
  get() {
    return props.modelValue
  },
  set(value) {
    emit('update:modelValue', value)
  }
})

六、最佳实践

命名规范

单一模型使用 defineModel()

多个模型使用 defineModel('name')

默认值设置

const value = defineModel({
  default: ''
})

复杂验证

const age = defineModel({
  type: Number,
  validator: (v) => v >= 0
})

与原生输入组件结合

<input
  :value="modelValue"
  @input="modelValue = $event.target.value"
>

七、对比传统方式

特性defineModel传统方式
代码量1行声明需要props + emit
类型支持自动推断需要手动定义
多模型支持参数指定名称需多个props/emit
修饰符处理内置支持需要手动实现
兼容性Vue 3.4+所有Vue3版本

八、实际案例

自定义计数器组件

Counter.vue

<script setup>
const count = defineModel<number>({ default: 0 })
</script>
<template>
  <button @click="count--">-</button>
  <span>{{ count }}</span>
  <button @click="count++">+</button>
</template>

父组件使用

<template>
  <Counter v-model="quantity" />
  <p>当前数量:{{ quantity }}</p>
</template>
<script setup>
const quantity = ref(1)
</script>

九、注意事项

  • 版本要求:必须使用 Vue 3.4 或更高版本
  • 单向数据流:虽然看起来像双向绑定,但仍然是单向数据流
  • 复杂逻辑:对于复杂场景,仍然可以使用传统方式
  • Ref解包:在模板中会自动解包,无需 .value

defineModel 是 Vue 3.4 中非常实用的新特性,它大幅简化了组件双向绑定的实现代码,同时保持了类型安全和灵活性。对于新项目,强烈推荐使用这种方式来实现 v-model 功能。

到此这篇关于全面剖析Vue3 全新特性 defineModel 的文章就介绍到这了,更多相关vue defineModel 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Vue中输入框仅支持数字输入的四种方法

    Vue中输入框仅支持数字输入的四种方法

    项目中需要用到大量的数字输入框限制,为了可以以后能又更多的拓展性,下面这篇文章主要给大家介绍了关于Vue中输入框仅支持数字输入的四种方法,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-08-08
  • Vue操作数组的几种常用方法小结

    Vue操作数组的几种常用方法小结

    本文主要介绍了Vue操作数组的几种常用方法小结,主要包括map、filter、forEach、find 和 findIndex 、some 和 every、includes、Array.from这几种方法,感兴趣的可以了解一下
    2023-09-09
  • vue利用openlayers实现动态轨迹

    vue利用openlayers实现动态轨迹

    这篇文章主要为大家介绍了vue利用openlayers实现动态轨迹,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-11
  • Vue3优雅的实现跨组件通信的常用方法总结

    Vue3优雅的实现跨组件通信的常用方法总结

    开发中经常会遇到跨组件通信的场景,props 逐层传递的方法实在是太不优雅了,所以今天总结下可以更加简单的跨组件通信的一些方法,文中通过代码实例讲解的非常详细,需要的朋友可以参考下
    2023-11-11
  • vue中使用postcss-px2rem的两种方法

    vue中使用postcss-px2rem的两种方法

    这篇文章主要介绍了vue项目中使用postcss-px2rem的方法总结,在项目中为了屏幕适配,经常会用到rem,postcss-px2rem就是为了让我们直接在将代码中px自动转化成对应的rem的一个插件,需要的朋友可以参考下
    2022-05-05
  • vue element table 表格请求后台排序的方法

    vue element table 表格请求后台排序的方法

    今天小编就为大家分享一篇vue element table 表格请求后台排序的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-09-09
  • Vue 计数器的实现

    Vue 计数器的实现

    这篇文章主要介绍了Vue 计数器的实现,主要利用HTML实现步骤现在页面上简单实现一个计数器,内容简单且详细,需要的朋友可以参考一下
    2021-10-10
  • vue如何判断数组中的对象是否包含某个值

    vue如何判断数组中的对象是否包含某个值

    这篇文章主要介绍了vue如何判断数组中的对象是否包含某个值,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08
  • vue+element树组件 实现树懒加载的过程详解

    vue+element树组件 实现树懒加载的过程详解

    这篇文章主要介绍了vue+element树组件 实现树懒加载的过程,本文通过图文实例代码相结合给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-10-10
  • vue+vue-validator 表单验证功能的实现代码

    vue+vue-validator 表单验证功能的实现代码

    这篇文章主要介绍了vue+vue-validator 表单验证功能的实现代码,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2017-11-11

最新评论