vue如何实现双向数据绑定
几种数据绑定实现方式
发布者-订阅者模式(.js)
脏检查(.js)
数据劫持(vue.js)
本文主要讲述vue双向数据绑定原理分析:
vue.js采用数据劫持结合发布者-订阅者模式的方式,通过.()来劫持各个属性的,,在数据变动时发布消息给订阅者,触发相应的监听回调。
. 方法提供了一种直接的方式来定义对象属性或者修改已有对象属性。其方法原型如下,.(obj, prop, )
<script>var obj = {}var returnVal = ""// 利用defineProperty去劫持更新// 第三个参数 数据描述 存取器的描述Object.defineProperty(obj, "age", {get:function () {return returnVal},set:function (newValue) {returnVal = newValue}})
</script>
对象obj获取属性key的值时,会触发上面的get方法,得到的是变量的值,然后当重新设置key的值时,触发set方法,会将变量的值改变为设置的值,如此就实现了一个简单的双向绑定:改变,obj.age得到的值也会改变,重新设置obj.age,一样会随之改变。
例子
实现随文本框输入文字的变化, 中会同步显示相同的文字内容;在js或控制台显式的修改 obj 中 name 的值,视图会相应更新。这样就实现了 model => view 以及 view => model 的双向绑定。
<script type="text/javascript" src="MyVue.js">script>
<body><div id="app"><input type="text" id="txt">input>输入:<span id="txtspan">span>div>
body>
当我们在输入框输入数据的时候,触发 keyup 事件,获取键盘的value 并赋值给 vm 实例的 name 属性。
var txt = document.getElementById("txt")
var txtspan = document.getElementById("txtspan")
var vm = new MyVue({el: "#app",data: {count: 0,name: "Cassie",age: 18}
})
txt.addEventListener("keyup", function (e) {vm._data.name = e.target.value
})
// 接受set的值
function callBack (val) {txtspan.innerHTML = val}
MyVue.js
将需要的数据对象进行递归遍历,包括子属性对象的属性,都加上 和 这样的话,给这个对象的某个值赋值,就会触发,那么就能监听到了数据变化。
// 数据监听
function Observer (value) {if (!value || (typeof value !== 'Object')) {return}// 获取data所有属性Object.keys(value).forEach((key) => {// 拦截defineReactive(value, key, value[key])})
}
// 拦截数据
function defineReactive (obj, key, val) {Object.defineProperty(obj, key, {get: function () {return val},set: function (newValue) {if (newValue === val) {return}val = newValuecallBack(val)}})
}
function MyVue (options) {this._data = options.dataObserver(this._data)
}