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: ()=>{
             /*....依赖收集等....*/
             /*Github:https://github.com/answershuto*/
         },
         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了。

原文链接:https://github.com/answershuto/learnVue/blob/master/docs/响应式原理.MarkDown

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值