Vue v-model 原理深度解析与自定义组件应用
本文深入解析 Vue 中 v-model 的实现原理,揭示其作为单项数据流语法糖的本质。详细阐述 v-model 在原生 input 元素与自定义组件中的默认行为差异,包括 value 属性与 input 事件的映射。针对 checkbox 等场景,介绍 Vue 2.2 引入的 model 选项如何定制 prop 和 event,解决默认行为不适用的问题,帮助开发者更灵活地构建可复用组件。
v-model 概述与背景
Vue 官方文档对 v-model 的说明相对简略,本文旨在深入剖析其内部机制,并介绍 Vue 2.2 版本中 v-model 的改进特性,同时穿插讲解相关的 Vue 核心概念。
Vue 在开发初期借鉴了 Angular 的许多设计思路,两者存在相似之处。但 Vue 解决了许多 Angular 早期版本中存在的问题,提供了更简洁的解决方案。
v-model 在 input 元素中的应用
当 v-model 应用于 input 元素时,其工作机制如下。
虽然 v-model 看起来类似于 Angular 中带有双向数据绑定的 ng-model,但 Vue 采用单向数据流架构,v-model 实际上只是语法糖。
<input v-model="sth" />
<input v-bind:value="sth" v-on:input="sth = $event.target.value" />
第一行代码实际上是第二行代码的简写形式,而第二行代码还可以进一步简化。
<input :value="sth" @input="sth = $event.target.value" />
理解这行代码的关键在于了解 input 元素的 oninput 事件。这是 HTML5 新增的事件,类似于 onchange,每当输入框内容发生变化时触发,并将最新的 value 传递给指定的变量 sth。
若不清楚 $event 的来源,建议查阅相关文档以复习其工作原理。
通过对比语法糖形式与原始语法形式,可以得出以下结论。
为 input 元素添加 v-model 属性时,默认将 value 作为元素的属性,并将 'input' 事件作为实时传递 value 的触发事件。
v-model 在自定义组件中的应用
当 v-model 应用于自定义组件时,其行为与原生元素有所不同。
v-model 不仅适用于 input 元素,也可用于组件。以下示例与 Vue 官方教程类似,阅读时需关注两个核心问题。

父组件中 price 的初始值为 100,修改子组件的值能够实时更新父组件中的 price 变量。
<div id="demo">
<currency-input v-model="price"></currentcy-input>
<span>{{price}}</span>
</div>
<script src="https://cdn.bootcss.com/vue/2.3.0/vue.js"></script>
<script>
Vue.component('currency-input', {
template: `
<span>
<input
ref="input"
:value="value"
<!--为什么这里把 'input' 作为触发事件的事件名?`input` 在哪定义的?-->
@input="$emit('input', $event.target.value)"
>
</span>
`,
props: ['value'],// 为什么这里要用 value 属性,value在哪里定义的?貌似没找到啊?
})
var demo = new Vue({
el: '#demo',
data: {
price: 100,
}
})
</script>
若能解答上述两个问题,说明已掌握 v-model 的核心用法;若仍有疑惑,请参考以下代码解析。
<currency-input v-model="price"></currentcy-input>
<!--上行代码是下行的语法糖
<currency-input :value="price" @input="price = arguments[0]"></currency-input>
-->
现在你应该清楚 value 和 input 的来源了。这与前文总结的规律类似。
为组件添加 v-model 属性时,默认将 value 作为组件的 prop 属性,并将 'input' 作为绑定事件时的事件名。
v-model 的局限性与定制方案
v-model 存在局限性,但在特定场景下有相应的解决办法。
在创建类似复选框或单选框的常见组件时,直接使用 v-model 可能会遇到困难。
<input type="checkbox" v-model="sth" />
v-model 默认提供 value 属性和 oninput 事件,但对于复选框,我们需要的是 checked 属性,且点击时触发的是 onchange 事件而非 oninput,这导致默认行为不适用。
由于 v-model 仅适用于 input 元素,因此处理此类情况相对简单。
<input type="checkbox" :checked="status" @change="status = $event.target.checked" />
当 v-model 应用于组件时,处理方式如下。
<my-checkbox v-model="foo"></my-checkbox>
Vue.component('my-checkbox', {
tempalte: `<input
type="checkbox"
@change="$emit('input', $event.target.checked)"
:checked="value"
/>`
props: ['value'],
})
在 Vue 2.2 版本中,可以通过 model 选项在定义组件时定制 prop 和 event。
<my-checkbox v-model="foo"></my-checkbox>
Vue.component('my-checkbox', {
tempalte: `<input
type="checkbox"
<!--这里就不用 input 了,而是 balabala-->
@change="$emit('balabala', $event.target.checked)"
:checked="value"
/>`
props: ['checked'], //这里就不用 value 了,而是 checked
model: {
prop: 'checked',
event: 'balabala'
},
})
至此,相信你已经全面理解了 Vue 的 v-model 机制。文中若有疏漏,欢迎在评论区指正,希望本文对你的学习有所帮助。
怎么在Vue3项目中集成轻量级JS文本编辑器
2026-11-03 12:21:35
Vue.js官网怎么切换Vue 2与Vue 3版本文档?避免看错版本指南
2026-11-03 08:08:08
ElementUI el-switch 开关组件使用详解与高级应用
2026-10-31 15:21:18
Element UI 表格行按钮点击加载与状态管理实现
2026-10-31 14:12:32
fullCalendar日历插件高级用法与源码修改实战
2026-10-31 10:19:16
