log
码中赤兔

Vue3.4 defineModel双向绑定

发布于 2025年1月4日
更新于 2025年1月4日
8 分钟阅读
Vue

在 Vue 3.4 版本之前,如果我们想在自定义组件中实现双向数据绑定,需要手动定义 modelValue 属性和 update:modelValue 事件,然后通过 computed 来实现绑定。这种方式虽然可行,但代码显得冗长且不够直观。

以下是 Vue 3.4 之前实现双向绑定的传统方法:

<!-- CustomInput.vue -->
<script setup lang="ts">
import { computed } from 'vue';

const props = defineProps<{
  modelValue: string;
}>();

const emits = defineEmits<{
  'update:modelValue': [value: string];
}>();

const value = computed({
  get: () => props.modelValue,
  set: (value: string) => emits('update:modelValue', value),
});
</script>

<template>
  <input v-model="value" />
</template>

在父组件中使用该组件时:

<!-- App.vue -->
<script setup lang="ts">
import { ref } from 'vue';
import CustomInput from './components/CustomInput.vue';

const inputValue = ref<string>('');
</script>

<template>
  <CustomInput v-model="inputValue" />
</template>

这种实现方式需要在 defineProps 中定义 modelValue,在 defineEmits 中定义 update:modelValue,再用一个 computed 处理数据绑定。虽然功能完整,但步骤复杂。


Vue 3.4 引入的新功能:defineModel

Vue 3.4 中新增了一个名为 defineModel 的函数,可以极大地简化双向数据绑定的实现。以下是使用 defineModel 的方法:

<!-- CustomInput.vue -->
<script setup lang="ts">
import { defineModel } from 'vue';

const val = defineModel<string>();
</script>

<template>
  <input v-model="val" />
</template>

defineModel 让我们无需显式声明 modelValueupdate:modelValue,并且直接支持 v-model 的双向绑定。这不仅简化了代码,还提升了可读性。


高级用法

1. 设置默认值

defineModel 支持直接为模型绑定指定默认值:

const val = defineModel({ type: String, default: '默认值' });

当父组件未传入绑定值时,子组件会使用默认值。

2. 多模型绑定

defineModel 还支持定义多个模型,用于处理复杂场景:

<!-- CustomInput.vue -->
<script setup lang="ts">
import { defineModel } from 'vue';

const name = defineModel<string>('name');
const address = defineModel<string>('address');
</script>

<template>
  <input v-model="name" placeholder="Name" />
  <input v-model="address" placeholder="Address" />
</template>

父组件使用示例:

<!-- App.vue -->
<script setup lang="ts">
import { ref } from 'vue';
import CustomInput from './components/CustomInput.vue';

const nameInput = ref<string>('John Doe');
const addressInput = ref<string>('123 Main St');
</script>

<template>
  <CustomInput v-model:name="nameInput" v-model:address="addressInput" />
</template>

这种方式让我们可以轻松绑定多个数据模型,代码更加灵活。


总结

defineModel 是 Vue 3.4 的一项重大更新,它让自定义组件的双向绑定变得更加简单和直观。通过 defineModel,我们不仅可以减少模板代码的复杂度,还可以更轻松地实现多模型绑定和默认值设置。如果你的项目能够升级到 Vue 3.4 及更高版本,强烈推荐使用 defineModel 来取代传统的 modelValue 实现方式。

关于

分享技术见解、经验和思考的个人博客

联系方式

  • Email: hushukang_blog@proton.me
  • GitHub

© 2025 码中赤兔. 版权所有