Vue的双向绑定 v-model的原理
使用V-model进行绑定
v-model的效果就是用户在输入的时候实际上实在修改txtVal的值,修改成用户输入的内容
<input type="text" v-model="txtVal">
<p>{{txtval}}</p>
使用ES6进行绑定
<input type="text" @input="inputChange" :value="txtval">
<p>{{txtval}}</p>
-
@input 输入事件,每次输入了新的元素,即为进行触发
-
:value 活化其value值
在模型层的方法
methods:{
inputChange(e){
this.txtval=e.target.value}
}
vue.js通过object.defineProperty()实现双向数据绑定
使用Object.defineProperty()进行绑定
语法:object.defineProperty(对象,属性,配置)
let obj={} //创建对象
//内置对象需要大写
Object.defineProperty(obj,"c",{
//进行对于obj自定义属性,C进行配置
value:150, //配置其值
writable:true, //表示可以进行更改
configurable:true, //表示可以进行删除
enumerable:true //表示可以进行遍历
})
obj.c=250 //进行更改
delete obj.c //进行删除
// 进行遍历:var i in obj 遍历出其中所有的元素
for(var i in obj){
console.log( "obj中含有的元素是",i)
}
使用get() set()方式进行配置 (!!主流)
Object.defineProperty(obj,"c",{
//注意!getset与设置value,writable等存在冲突,无法同时使用
get(){
//get中的return就设置了使用get时的 b的值
return 100
},
set(val){
//在set中绑定形参val,就会在调用set时把数值流入set方法之中
console.log("调用了set",val);//"调用了set",1000
}})
obj.b=1000 //修改b的值进行触发set方法
console.log(obj.b); //访问b的值,触发get方法
Object.defineProperty()的原理
双向数据绑定的原理:借助Object.defineProperty()对数据进行劫持,并结合发布-订阅者模式,来实现双向数据绑定
hc:
<input type="text" id="inp">
<p id="txt"></p>
js:
let data={info:"hello"}//模拟new Vue中的data属性
let vm={} //模拟一个Vue的实例化对象
Object.defineProperty(vm,"info",{
get(){
//获取到data仓库中的值并且向外部返回
return data.info
},
set(val){
//set事件进行了数据劫持,劫持到了要修改的数据为val形参
data.info=val
document.getElementById("txt").innerHTML=vm.info
}
})
//将data中的数据静态绑定在视图层 即为 input与p当中
//更新dom以用于显示数据 [订阅者 p]
document.getElementById("inp").value=vm.info
document.getElementById("txt").innerHTML=vm.info
//给文本框绑定一个事件监听,以用于属于事件的操作
//addEventListener("操作的事件",处理的函数)
document.getElementById("inp").addEventListener("input",function(e){
//获取页面的最新值,并且更新到vm.info之上[发布者,发布最新的数据]
vm.info=e.target.value
})
-
访问到info时,就会触发get函数
-
当设置修改了info的时候,触发了set函数.形参val就会传进函数内进行对绑定了的data的值进行修改
-
通过事件监听,当调用到set方法时,添加动态更新数据,更新data.info为输入的值
-
此时在set方法中再次调用get方法,使得新的值更新在视图之中
结论
v-model本质上只是语法糖,是由
:value="txtVal" @input="txtVal=$event.target.value"
组成了v-model
即为方法也可以写成行内事件
<input type="text" :value="txtVal" @input="txtVal=$event.target.value" placeholder="初始值">