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
数据属性。如此一来,数据就会随着用户的输入实时更新。