现在我们来简单讲解一下vue中的数据双向绑定的实现,也就是vue指令v-model,v-model语法糖的拆解和原生js中Object.definedProperty()实现数据双向绑定。
vue的双向数据绑定是通过,数据劫持结合发布定订阅者模式来实现的,也就是说数据和视图同步更新,数据发生变化视图也跟着变化,数视图变化,数据也跟着变化。
Vue中的双向数据绑定
v-model
v-model指令是vue中实现数据双向绑定的指令,我们先看代码。
代码:
<div id="app">
<input type="text" id="a" v-model="msg">
<span id="b">{
{msg}}</span>
</div>
let vm = new Vue({
el: '#app',
data: {
msg: 'span标签'
}
})
效果如图:
以上代码很简单的实现了,input框内容和span标签文字的双向数据绑定。
v-model的另一种实现方法
v-model是一个语法糖,现在我们使用另一种写法来实现v-model的功能,来了解v-model的工作原理。
代码:
<div id="app">
<input type="text" id="a" v-bind:value="msg" v-on:input="handle">
<span id="b">{
{msg}}</span>
</div>
let vm = new Vue({
el: "#app",
data: {
msg: 'hello'
},
methods: {
handle: function (event) {
this.msg = event.target.value
}
}
})
效果和v-model一样可以实现数据的双向绑定。
如此可见,我们使用了v-bind为输入框的内容绑定了data里面的数据msg,然后用v-on为输入框写了一个input事件,使得事件触发时,输入框的数据可以赋值给data里面的msg。而span标签内的
所以v-model做了两件事,一是用v-bind把data里面的数据绑定在相应的元素上,二是用v-on为元素写一个事件,触发这个事件的时候把元素内的值赋值给data里面的数据。
我们还可以去稍微简化一下上面的代码。
如下:
<div id="app">
<input type="text" id="a" v-bind:value="msg" v-on:input="msg=$event.target.value">
<span id="b">{
{msg}}</span>
</div>
let vm = new Vue({
el: "#app",
data: {
msg: 'hello'
},
})
如上可见,我们省略了methods里面的事件函数,直接把这个函数的代码写到了v-on绑定的事件input里面,大大减少了代码量。但如果事件函数很复杂的话不建议这样书写。
js实现数据双向绑定-Object.definedProperty()
使用原生js实现数据双向绑定,主要是依靠Object.definedProperty()。
语法:Object.definedProperty(obj,prop,desxriptor)
- obj (被定义或修改属性的对象)
- prop (被定义或修改的属性)
- desxriptor (具体改变的方法 ,是对象)
- 每一个属性都有get 和set 的方法 用来获取值和修改值
数据双向绑定的实现,代码与注释如下:
<input type="text" id="a">
<span id="b"></span>
var obj = {}//先定义一个空对象
var val = 'dageda'//先定义一个val,定义一个初始值
Object.defineProperty(obj, 'val', {
get: function () {//get方法,获取的时候触发
return val
},
set: function (newVal) {//set方法,设置该属性的时候触发 因为是设置 所以需要传入参数
val = newVal
document.getElementById('a').value = val//把val的值赋值给id为a的元素
document.getElementById('b').innerHTML = val//同上
}
})
document.addEventListener('keyup', function (e) {//监听键盘按键抬起事件
obj.val = e.target.value //把输入框的值赋值给对象obj里面的属性val
})
如上也可以实现数据的双向绑定。