vue实现vmodel
Vue 实现 v-model 双向绑定
v-model 是 Vue 提供的语法糖,用于在表单元素或自定义组件上实现双向数据绑定。其本质是 value 属性和 input 事件的组合。
在表单元素中使用 v-model
Vue 内置了对常见表单元素(如 input、textarea、select)的 v-model 支持。
<template>
<input v-model="message" placeholder="Edit me">
<p>Message is: {{ message }}</p>
</template>
<script>
export default {
data() {
return {
message: ''
}
}
}
</script>
自定义组件实现 v-model
在自定义组件中实现 v-model 需要显式定义 model 选项或使用 v-bind 和 v-on 的语法糖。
方法 1:使用 model 选项
<template>
<custom-input v-model="searchText"></custom-input>
</template>
<script>
export default {
data() {
return {
searchText: ''
}
}
}
</script>
<!-- CustomInput.vue -->
<template>
<input
:value="value"
@input="$emit('input', $event.target.value)"
>
</template>
<script>
export default {
props: ['value'],
model: {
prop: 'value',
event: 'input'
}
}
</script>
方法 2:Vue 2.2+ 的语法糖

<custom-input
:value="searchText"
@input="searchText = $event"
></custom-input>
Vue 3 中的变化
Vue 3 对 v-model 进行了改进,支持多个 v-model 绑定和自定义修饰符。
基本用法
<custom-input v-model="searchText"></custom-input>
等效实现

<custom-input
:modelValue="searchText"
@update:modelValue="searchText = $event"
></custom-input>
自定义组件实现
<!-- CustomInput.vue -->
<template>
<input
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
>
</template>
<script>
export default {
props: ['modelValue'],
emits: ['update:modelValue']
}
</script>
多个 v-model 绑定
<user-name
v-model:first-name="firstName"
v-model:last-name="lastName"
></user-name>
<!-- UserName.vue -->
<template>
<input
:value="firstName"
@input="$emit('update:firstName', $event.target.value)"
>
<input
:value="lastName"
@input="$emit('update:lastName', $event.target.value)"
>
</template>
<script>
export default {
props: {
firstName: String,
lastName: String
},
emits: ['update:firstName', 'update:lastName']
}
</script>
修饰符处理
可以自定义修饰符处理逻辑:
<custom-input v-model.capitalize="text"></custom-input>
<!-- CustomInput.vue -->
<template>
<input
:value="modelValue"
@input="emitValue"
>
</template>
<script>
export default {
props: {
modelValue: String,
modelModifiers: {
default: () => ({})
}
},
emits: ['update:modelValue'],
methods: {
emitValue(e) {
let value = e.target.value
if (this.modelModifiers.capitalize) {
value = value.charAt(0).toUpperCase() + value.slice(1)
}
this.$emit('update:modelValue', value)
}
}
}
</script>
通过以上方法可以在 Vue 中灵活实现各种 v-model 双向绑定需求。






