vue v model 实现
Vue v-model 实现原理
Vue 的 v-model 是一个语法糖,用于在表单元素或组件上实现双向数据绑定。其核心是通过 value 属性和 input 事件的组合来实现数据同步。
基本实现方式:
在原生表单元素上,v-model 会根据元素类型自动绑定不同的属性和事件:
- 对于
<input type="text">和<textarea>,绑定value属性和input事件。 - 对于
<input type="checkbox">和<input type="radio">,绑定checked属性和change事件。 - 对于
<select>,绑定value属性和change事件。
在表单元素中使用 v-model
以下是一个简单的示例,展示如何在表单元素中使用 v-model:
<template>
<div>
<input type="text" v-model="message" />
<p>{{ message }}</p>
</div>
</template>
<script>
export default {
data() {
return {
message: ''
};
}
};
</script>
在自定义组件中实现 v-model
在自定义组件中,可以通过 model 选项配置 v-model 的绑定属性和事件。默认情况下,v-model 会使用 value 作为 prop 和 input 作为事件。
自定义组件的实现:
<template>
<div>
<custom-input v-model="message"></custom-input>
<p>{{ message }}</p>
</div>
</template>
<script>
export default {
data() {
return {
message: ''
};
},
components: {
'custom-input': {
props: ['value'],
template: `
<input
type="text"
:value="value"
@input="$emit('input', $event.target.value)"
/>
`
}
}
};
</script>
使用 model 选项自定义 prop 和事件
如果需要自定义 v-model 绑定的 prop 和事件,可以使用 model 选项:
<template>
<div>
<custom-checkbox v-model="checked"></custom-checkbox>
<p>{{ checked ? 'Checked' : 'Unchecked' }}</p>
</div>
</template>
<script>
export default {
data() {
return {
checked: false
};
},
components: {
'custom-checkbox': {
model: {
prop: 'checked',
event: 'change'
},
props: ['checked'],
template: `
<input
type="checkbox"
:checked="checked"
@change="$emit('change', $event.target.checked)"
/>
`
}
}
};
</script>
Vue 3 中的 v-model 变化
在 Vue 3 中,v-model 的实现有所调整:
- 默认使用
modelValue作为 prop 和update:modelValue作为事件。 - 支持多个
v-model绑定,例如v-model:title和v-model:content。
Vue 3 示例:
<template>
<custom-input v-model="message"></custom-input>
</template>
<script>
export default {
data() {
return {
message: ''
};
},
components: {
'custom-input': {
props: ['modelValue'],
emits: ['update:modelValue'],
template: `
<input
type="text"
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
/>
`
}
}
};
</script>
总结
v-model 的核心是通过绑定指定的 prop 和事件实现双向数据同步。在原生表单元素中,Vue 会自动处理这些绑定;在自定义组件中,可以通过 model 选项或 Vue 3 的默认约定来实现。







