麦子学院 2017-08-24 11:38
Vue.js响应式原理
回复:0 查看:2425
本文和大家分享的主要是Vue.js
响应式原理相关内容,一起来看看吧,希望对大家
学习Vue.js有所帮助。
关于Vue.js
Vue.js
是一款
MVVM
框架,上手快速简单易用,通过响应式在修改数据的时候更新视图。
Vue.js
的响应式原理依赖于
Object.defineProperty
,尤大大在Vue.js
文档中就已经提到过,这也是
Vue.js
不支持
E8
以及更低版本浏览器的原因。
Vue
通过设定对象属性的
setter/getter
方法来监听数据的变化,通过
getter
进行依赖收集,而每个
setter
方法就是一个观察者,在数据变更的时候通知订阅者更新视图。
将数据data变成可观察(observable)的
那么Vue
是如何将所有
data
下面的所有属性变成可观察的(
observable
)呢?
function
observer(value) {
Object.keys(value).forEach((key) => defineReactive(value, key, value[key] , cb))
}
function
defineReactive (obj, key, val, cb) {
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get: ()=>{
/*....
依赖收集等
....*/
},
set:newVal=> {
cb();/*
订阅者收到消息的回调
*/
}
})
}
class
Vue {
constructor(options) {
this._data = options.data;
observer(
this._data, options.render)
}
}
let app =
new Vue({
el: '#app',
data: {
text: 'text',
text2: 'text2'
},
render(){
console.log("render");
}
})
为了便于理解,首先考虑一种最简单的情况,不考虑数组等情况,代码如上所示。在
initData
中会调用
observe
这个函数将Vue
的数据设置成
observable
的。当
_data
数据发生改变的时候就会触发
set
,对订阅者进行回调(在这里是
render
)。
那么问题来了,需要对app._date.text
操作才会触发
set
。为了偷懒,我们需要一种方便的方法通过
app.text
直接设置就能触发
set
对视图进行重绘。那么就需要用到代理。
代理
我们可以在Vue
的构造函数
constructor
中为
data
执行一个代理
proxy
。这样我们就把data
上面的属性代理到了
vm
实例上。
_proxy(options.data);/*
构造函数中
*/
/*
代理
*/
function
_proxy (data) {
const that =
this;
Object.keys(data).forEach(key => {
Object.defineProperty(that, key, {
configurable: true,
enumerable: true,
get:
function
proxyGetter () {
return that._data[key];
},
set:
function
proxySetter (val) {
that._data[key] = val;
}
})
});
}
我们就可以用app.text
代替
app._data.text
了。
.js
来源:
稀土掘金