v-model原理详解

一 :value="msg
在 Vue.js 中,v-bind 指令(简写为 :)用于将数据属性绑定到 HTML 元素的属性上。当你使用 :value="msg" 时,它的作用是将 Vue 实例中的 msg 数据属性绑定到目标元素的 value 属性上。
1.value 属性的作用
- 单向数据绑定:将
msg的值传递给 HTML 元素(如输入框、选择框等),但不会自动将用户输入的值同步回msg。 - 视图驱动:当
msg的值发生变化时,HTML 元素的value会自动更新,但用户在 HTML 元素中输入内容时,msg不会自动更新(需要手动处理事件)。
2.代码示例
⑴. 基本用法
<template><div id="app"><!-- 使用 :value 绑定 msg 到输入框 --><input :value="msg" type="text"><p>当前输入内容:{{ msg }}</p></div>
</template><script>
export default {data() {return {msg: 'Hello Vue!'};}
};
</script>
效果:
- 输入框的
value初始值为Hello Vue!(来自msg)。 - 如果你在输入框中输入新内容,
msg不会自动更新(因为:value是单向绑定)。


⑵. 手动更新数据
如果需要将用户输入的值同步到 msg,需要手动监听事件(如 @input)并更新数据:
<template><div id="app"><!-- 使用 :value 绑定 msg,同时监听 input 事件 --><input :value="msg" @input="updateMsg" type="text"><p>当前输入内容:{{ msg }}</p></div>
</template><script>
export default {data() {return {msg: 'Hello Vue!'};},methods: {updateMsg(event) {// 手动更新 msgthis.msg = event.target.value;}}
};
</script>


效果:
- 输入框的
value初始值为Hello Vue!。 - 当用户输入内容时,
updateMsg方法会被调用,将输入值赋给msg,实现双向绑定。
二、@input 等同于什么
在 Vue.js 中,@input 是 v-on:input 的缩写形式,它是一个事件指令,用于监听 DOM 元素的 input 事件。当用户在输入框等表单元素中输入内容时,就会触发 input 事件。
1.语法糖与完整写法
@input 是语法糖,其完整写法是 v-on:input。下面通过代码示例来说明二者是等价的:
<template><!-- 使用 @input 缩写形式 --><input type="text" @input="handleInput"><!-- 使用 v-on:input 完整形式 --><input type="text" v-on:input="handleInput">
</template><script setup>
const handleInput = (event) => {console.log('输入内容:', event.target.value);
};
</script>
2.与原生 input 事件的关联
在原生 JavaScript 里,要监听输入框的 input 事件,通常会使用 addEventListener 方法。在 Vue 中,@input 指令其实是对原生 input 事件的封装,简化了事件监听的代码书写。下面对比原生 JavaScript 和 Vue 的写法:
原生 JavaScript 示例
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8">
</head><body><input type="text" id="myInput"><script>const inputElement = document.getElementById('myInput');inputElement.addEventListener('input', function (event) {console.log('输入内容:', event.target.value);});</script>
</body></html>
Vue 示例
<template><input type="text" @input="handleInput">
</template><script setup>
const handleInput = (event) => {console.log('输入内容:', event.target.value);
};
</script>
可以看到,Vue 的 @input 指令让事件监听的代码更加简洁,不需要手动获取 DOM 元素并添加事件监听器。
三、input 事件
input 事件主要在相关元素的 value 值发生变化时触发,输入内容是触发该事件的常见情形,但不仅限于此。具体触发机制如下:
1. 输入内容触发的场景
当用户在 <input>、<textarea> 等元素中进行以下操作时,会触发 input 事件:
- 键盘输入:每输入一个字符,
input事件都会立即触发。 - 粘贴文本:将剪贴板内容粘贴到输入框时。
- 删除字符:通过键盘删除键或鼠标选中删除内容时。
- 拖放内容:将文本拖放到输入框中。
2. 其他触发场景
- 代码动态修改值:通过 JavaScript 直接修改元素的
value属性(如element.value = '新内容'),也会触发input事件。 - 特殊元素:对
<input type="checkbox">或<input type="radio">等元素,用户切换状态时(如勾选或取消勾选),input事件也会触发(但需注意部分旧浏览器兼容性,必要时可用change事件替代)。 - 富文本编辑:对启用
contenteditable属性的元素(如<div contenteditable="true">)或开启designMode的页面元素,内容变化时也会触发input事件。
3.与 change 事件的区别
input 事件即时响应值的变化,只要 value 改变就触发;而 change 事件在值改变且元素失去焦点时(如输入框失焦、下拉框选择完成)才触发。例如:
- 输入框中每输入一个字符,
input事件立即触发,而change事件需等输入完成并移开焦点才触发。
综上,输入内容是触发 input 事件的典型场景,但该事件本质是监听 value 值的变化,只要值改变(无论用户操作还是代码修改),通常都会触发。
四、@input="msg = $event.target.value
当用户在绑定了 @input 指令的元素中输入内容时,input 事件就会触发,然后执行 msg = $event.target.value 这个赋值操作,把输入框中的当前值赋给 Vue 实例中的 msg 数据属性。如此一来,数据就会随着用户的输入实时更新。
