Vue3 中的 v-model 指令有什么变化?
约 766 字大约 3 分钟
2025-03-13
总结
Vue3
和 Vue2
的 v-model
的基本功能几乎没有区别。但是Vue3
在以下几个方面有变化:
- 统一性:所有双向绑定均通过
v-model
实现,移除.sync
,减少概念负担。 - 可扩展性:支持封装自定义修饰符,实现更丰富的逻辑控制。
- 灵活性:支持多个
v-model
绑定,适用于复杂组件(如表单、配置面板)。 - 明确性:属性名和事件名更语义化(
modelValue
替代value
),主要为了配个多个v-model
的绑定
在 Vue.js 3 中,v-model 指令的功能保持了与 Vue.js 2 相似,用于在表单元素和组件之间建立双向绑定。然而,v-model 指令在 Vue.js 3 中经历了一些变化:
指令参数变为自定义
在 Vue.js 2 中,v-model 指令必须带有一个参数来指定绑定的属性、变量或表达式。而在 Vue.js 3 中,v-model 指令的参数变为可选项,可以省略参数。v-model:title='bookTitle'
,title 可省略。
<MyComponent v-model:title="bookTitle" />
处理自定义指令的方式不同
在 Vue.js 2 中,使用 v-model 指令绑定自定义组件时,组件需要有一个名为 value 的 prop,以及一个名为 input 的自定义事件。而在 Vue.js 3 中,可以通过使用modelValue
和 update:modelValue
来替代value
和input
。
<!-- MyComponent.vue -->
<script>
export default {
props: ['title'],
emits: ['update:title']
}
</script>
<template>
<input
type="text"
:value="title"
@input="$emit('update:title', $event.target.value)"
/>
</template>
自定义指令修饰符
在 Vue 3 中,你可以自定义模型修饰符,从而能够更好地适应不同的输入组件类型。Vue 2 中的 v-model 仅支持 .trim 和 .number 两种默认修饰符,而 Vue 3 中可以自定义任意修饰符,以便在特定情况下转换数据。
对于又有参数又有修饰符的 v-model
绑定,生成的 prop 名将是 arg + "Modifiers"
。
假如我们要实现capitalize
这个修饰符,其功能是首字母转化为大写:
<MyComponent v-model:title.capitalize="myText" />
绑定的title
对应如下:
export default {
props: ["title", "titleModifiers"],
emits: ["update:title"],
created() {
console.log(this.titleModifiers); // { capitalize: true }
},
};
具体处理:
<script>
export default {
props: {
title: String,
titleModifiers: {
default: () => ({}),
},
},
emits: ["update:title"],
methods: {
emitValue(e) {
let value = e.target.value;
if (this.titleModifiers.capitalize) {
value = value.charAt(0).toUpperCase() + value.slice(1);
}
this.$emit("update:title", value);
},
},
};
</script>
<template>
<input type="text" :value="title" @input="emitValue" />
</template>
支持多个 v-model
组件上可以绑定多个 v-model 来实现双向绑定,每一个不同的 v-model 都可以绑定不同的 prop。
// 父组件
<UserName v-model:first-name="first" v-model:last-name="last" />
// 子组件
<script>
export default {
props: {
firstName: String,
lastName: String,
},
emits: ["update:firstName", "update:lastName"],
};
</script>
<template>
<input
type="text"
:value="firstName"
@input="$emit('update:firstName', $event.target.value)"
/>
<input
type="text"
:value="lastName"
@input="$emit('update:lastName', $event.target.value)"
/>
</template>
这些变化使得 v-model 指令在 Vue.js 3 中更加统一和一致,同时也提供了更灵活的使用方式。需要注意的是,由于这些变化,升级到 Vue.js 3 时需要进行相应的修改和适配。
更新日志
e7112
-1于