赞
踩
简述: Vuejs 的响应式依赖于Object.defineProprtry,通过监听对象属性 的setter/getter 的变化,通过getter 进行依赖收集,而setter相当于观察者,数据产生变化的时候通知「订阅者」更新视图。
所谓要实现双向数据绑定,vue中内部采用了发布-订阅模式。内部结合了Object.defineProperty这个ES5的新特性(ie8浏览器可不支持哦…),对vue传入的数据进行了相应的数据拦截,为其动态添加get与set方法。当数据变化的时候,就会触发对应的set方法,当set方法触发完成的时候,内部会进一步触发watcher,当数据改变了,接着进行虚拟dom对比,执行render,后续视图更新操作完毕
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <title>kkk</title> </head> <body> <div id="app"></div> <script> var datas = {a:0}, active; // active 用来记录 watcher // 2, 定义一个defineAttr方法,将当前"值状态"改变的状态变成响应式的 function defineAttr(obj) { // 对对象里面的每一个属性都用 Object.defineProprety() 定义一下 for (let key in obj){ let value = obj[key] // 当我们要get 取值的时候就需要把当前的值进行保存 let dep = []; // 定义一个空数组用来接收active, 保存当前的watcher // dep 里面放的是依赖,啥事依赖呢?依赖就是 watcher Object.defineProperty(obj, key, { get() { // 当 datas.a 时走get 取数据 if(active) { dep.push(active) } console.log('this is get') return value // 取值的时候给他当前值 }, set(newVlue) { // 当 datas.a = 100 时走set 设置值 console.log('this is set') value = newVlue // 当要改变值的时候就需要将当前值换成newValue dep.forEach(watcher => watcher()) } }) } } defineAttr(datas) // 1,watcher 为订阅函数,只要"值状态"发生了改变就会去改变视图 // 所以就要对datas 里面的数据进行监听,看他的值的状态 const watcher = (fn)=> { active = fn; // 4, 用watcher 来记录一下 watcher 订阅函数 fn(); active = null // 如果在 外面触发 get 那就 } watcher(()=>{ app.innerHTML = datas.a // 3, 当 datas.a 的时候需要执行get取值操作 }) </script> </body> </html>
将data对象的值通过Object.defineProperty 中的set方法监听修改读取数据,在执行set时,既现在值发生改变,执行发布者类中的notify 将订阅者名单里的对象进行遍历调用其对象自身的update更新方法,这样修改其中一个该key对应的value,其在此页面上所有的该key对象都将执行update进行更新最新值来达到数组的响应式和一致性。
转载于,请查看原文
https://blog.csdn.net/kzj0916/article/details/108298865
1,数据改变,通过object.defineproperty的get 和 set方法进行捕获,get方法读取操作,set修改操作;
2,数据修改,被set方法捕获到,在set方法中对值进行改变,同时调用"发布者"的方法;
3,发布者就是把用到的该对象中的同一个key放在数组里进行观察;
4,发布者通过notify方法 对该数组中的所有元素遍历,即所有被观察的,传入修改的值;
5,遍历的每个元素,都被放进"订阅者watch"中进行修改,做到数据一致,实时更新。
6,订阅者watch就是被发布者进行遍历,完了根据发布者传进来的值进行更新修改;
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。