v-model 在 Vue2 版本的本质上不过是语法糖,v-model 会忽略所有表单元素的 value、checked、selected attribute 的初始值而总是将 Vue 实例的数据作为数据来源,v-model 在内部为不同的输入元素使用不同的 property 并抛出不同的事件:
text 和 textarea 元素使用 value property 和 input 事件;
checkbox 和 radio 使用 checked property 和 change 事件;
select 字段将 value 作为 prop 并将 change 作为事件。
Vue3 版本的 v-model 做了修改。

1、实现方法一

1、将内部原生 input 元素的 value attribute(属性) 绑定到 modelValue prop

2、输入新的值时在 input 元素上触发 update:modelValue 事件

1
2
3
4
5
6
7
8
9
10
11
<script setup>
defineProps(['modelValue'])
defineEmits(['update:modelValue'])
</script>

<template>
<input
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
/>
</template>

2、实现方法二:

利用计算属性:watch 具有 get 和 set 方法,get 方法需要返回 modelValue prop ,而 set 方法触发相应的事件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<script setup>
import { computed } from 'vue'

const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])

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

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

3、多个 v-model 绑定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<script setup>
defineProps({
firstName: String,
lastName: String
})

defineEmits(['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>
1
<UserName v-model:first-name="first" v-model:last-name="last" />