vue实现vmodel
Vue 实现 v-model
Vue 的 v-model 是一个语法糖,用于在表单元素或组件上实现双向数据绑定。以下是其实现方式和原理的详细说明。
在表单元素上使用 v-model
v-model 在原生表单元素(如 input、textarea、select)上的实现本质上是监听 input 或 change 事件,并动态更新绑定的数据。
<input v-model="message" />
等价于:
<input
:value="message"
@input="message = $event.target.value"
/>
在自定义组件上使用 v-model
在 Vue 2 中,v-model 默认绑定到 value prop 和 input 事件。可以通过 model 选项修改默认行为。
Vue.component('custom-input', {
props: ['value'],
model: {
prop: 'value',
event: 'input'
},
template: `
<input
:value="value"
@input="$emit('input', $event.target.value)"
/>
`
});
在 Vue 3 中,v-model 的行为有所变化,支持多个 v-model 绑定,并默认使用 modelValue prop 和 update:modelValue 事件。
app.component('custom-input', {
props: ['modelValue'],
emits: ['update:modelValue'],
template: `
<input
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
/>
`
});
自定义 v-model 修饰符
Vue 允许为 v-model 添加修饰符,例如 .trim、.number 或 .lazy。在自定义组件中,可以通过 modelModifiers prop 访问修饰符。
app.component('custom-input', {
props: {
modelValue: String,
modelModifiers: {
default: () => ({})
}
},
emits: ['update:modelValue'],
template: `
<input
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
/>
`,
created() {
console.log(this.modelModifiers); // 输出修饰符对象
}
});
实现双向绑定的底层原理
v-model 的核心是结合 :value(或 :modelValue)和 @input(或 @update:modelValue)实现数据同步。以下是 Vue 3 的实现示例:
const app = Vue.createApp({
data() {
return {
message: ''
};
},
template: `
<custom-input v-model="message" />
`
});
app.component('custom-input', {
props: ['modelValue'],
emits: ['update:modelValue'],
template: `
<input
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
/>
`
});
app.mount('#app');
多 v-model 绑定(Vue 3 特有)
Vue 3 支持为单个组件绑定多个 v-model,例如:
<user-name
v-model:first-name="firstName"
v-model:last-name="lastName"
/>
对应的组件实现:
app.component('user-name', {
props: {
firstName: String,
lastName: String
},
emits: ['update:firstName', 'update:lastName'],
template: `
<input
:value="firstName"
@input="$emit('update:firstName', $event.target.value)"
/>
<input
:value="lastName"
@input="$emit('update:lastName', $event.target.value)"
/>
`
});
通过以上方法,可以灵活地在 Vue 中实现 v-model 的双向绑定功能。







