v-model的四种实现方式

Vue.js是一个非常流行的前端JavaScript框架,它使得构建用户界面变得简单而高效。其中,v-model指令是实现表单输入和其他组件之间的双向数据绑定的关键工具。本文将以Vben Admin框架为例,探讨Vue 3中v-model的不同实现方式,并通过具体的代码示例展示如何应用这些方法。


B站课程


Vue 3中的v-model基础

v-model vs v-model:modelValue vs v-model:value

  • v-model:默认情况下,v-model会绑定到名为modelValue的prop上,并监听update:modelValue事件。
  • v-model:modelValue:明确指定绑定的prop名称为modelValue
  • v-model:value:指定绑定的prop名称为value,并监听update:value事件。

实现方式一:传统的props与emit组合

视频讲解open in new window

示例(VModel1.vueVModel2.vue

<!-- VModel1.vue -->
<script setup lang="ts">
import { ref, watch } from 'vue';
import { Input } from 'ant-design-vue';

const props = defineProps({
  modelValue: {
    type: String,
    default: '',
  },
});
const emits = defineEmits(['update:modelValue']);
const mValue = ref(props.modelValue);

watch(
  () => props.modelValue,
  (val) => {
    mValue.value = val;
  }
);

const handleInputChange = (e: any) => {
  emits('update:modelValue', e.target.value);
};
</script>

<template>
  <Input v-model:value="mValue" @change="handleInputChange" />
</template>

这种方式通过手动定义props和emits来实现双向绑定,适用于需要灵活控制数据流的场景。

实现方式二:计算属性结合get/set方法

视频讲解open in new window

示例(VModel21.vueVModel22.vue

<!-- VModel21.vue -->
<script setup lang="ts">
import { computed } from 'vue';
import { Input } from 'ant-design-vue';

const props = defineProps({
  modelValue: {
    type: String,
    default: '',
  },
});
const emits = defineEmits(['update:modelValue']);

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

<template>
  <Input v-model:value="mValue" />
</template>

利用计算属性的getter和setter功能,简化了数据绑定逻辑,使代码更加简洁易读。

实现方式三:@vueuse/core库的useVModel函数

视频讲解open in new window

示例(VModel31.vueVModel32.vue

<!-- VModel31.vue -->
<script setup lang="ts">
import { useVModel } from '@vueuse/core';
import { Input } from 'ant-design-vue';

const props = defineProps({
  modelValue: {
    type: String,
    default: '',
  },
});
const emits = defineEmits(['update:modelValue']);

const mValue = useVModel(props, 'modelValue', emits);
</script>

<template>
  <Input v-model:value="mValue" />
</template>

通过@vueuse/core库提供的useVModel函数,可以快速实现v-model绑定,减少样板代码,提高开发效率。

实现方式四:defineModel宏的使用

视频讲解open in new window

从 Vue 3.4 开始,推荐的实现方式是使用 defineModel() 宏:

defineModel 是一个便利宏。编译器将其展开为以下内容:

  • 一个名为 modelValueprop,本地 ref 的值与其同步;
  • 一个名为 update:modelValue 的事件,当本地 ref 的值发生变更时触发。

示例(VModel41.vueVModel42.vue

<!-- VModel41.vue -->
<script setup lang="ts">
import { Input } from 'ant-design-vue';

const mValue = defineModel<string>('modelValue');
</script>

<template>
  <Input v-model:value="mValue" />
</template>

这种方式提供了一种更加声明式的方式来处理v-model,减少了对props和emits的手动管理。

结论

通过以上四种不同的实现方式,我们可以根据项目的具体需求选择最合适的方案。每种方法都有其独特的优势,开发者应综合考虑项目复杂度、维护成本等因素来做出最佳选择。

配套示例源码地址open in new window

参考资料