实现一个简单得数据响应系统


Posted in Javascript onNovember 11, 2021

1、Dep

其实,这就是一个依赖收集的容器, depend 收集依赖, notify 触发依赖

class Dep{
  constructor() {
    this._subs = [];
  }
  depend () {
    this._subs.push(Dep.target)
  }
  notify() {
    this._subs.forEach(item => {
      item.fn();
    })
  }
}

// 其实就是 dep 和 watcher 基情满满的开始,watcher 中用到
// 通过一个全局属性来存 watcher
Dep.target = null;

function pushTarget(watch) {
  Dep.target = watch;
}

function popTarget() {
  Dep.target = null;
}

2、了解 obverser

递归,将 data 对象所有属性转化为访问器属性

// 转为访问器属性
function defineReactive (obj, key, val, shallow) {

  // 创建一个依赖收集容器
  let dep = new Dep();
  let childOb = !shallow && observe(val)

  Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get: function reactiveGetter () {
      if(Dep.target) {
        // 收集依赖
        dep.depend();
      }
      return val;
      // ...
    },
    set: function reactiveSetter (newVal) {
      if(newVal === val) return;
      // 继续递归遍历
      observe(newVal);
      // 触发依赖
      dep.notify();
      // ...
    }
  })
}

class Observer{
  constructor(data) {
    this.walk(data);
  }

  walk(data) {
    const keys = Object.keys(data)
    for (let i = 0; i < keys.length; i++) {
      defineReactive(data, keys[i], data[keys[i]])
    }
  }
}

// 递归,将 data 对象所有属性转化为访问器属性
function observe (data) {
  if(Object.prototype.toString.call(data) !== '[object Object]') return;
  new Observer(data);
}

此时就可以把任意一个对象的全部属性转为访问器

3、了解 watch 和 observer

const data = {
  a: 1,
  b: 2
}

// 首先监控一个对象
observe(data);

watcher 的主要功能是检测某个属性,当属性变化时触发一个回调

class Watcher{
  /**
  * @params {Function} exp 一个属性表达式
  * @params {Function} fn 回调
  */
  constructor(exp, fn) {
    this.exp = exp;
    this.fn = fn;

    // 存 watcher
    // Dep.target = this;
    pushTarget(this);

    // 先执行一次表达式函数,会在调用过程中,
    // 触发到 data.a 的访问器, data.a 的 get 被执行,
    // 触发 dep.depend() 开始收集依赖
    this.exp();

    // 释放 Dep.target
    popTarget();
  }
}

// new Watcher 这样一个依赖就被收集了
new Watcher(() => {
  return data.a + data.b;
}, () => {
  console.log('change')
})

4、触发依赖

data.a = 3; // change
data.b = 3; // change

5、总结一下流程

  • 把一个对象的全部属性转化为访问器
  • 当为某一个属性增加 watcher 时,会触发改属性的 getget 函数中会把该 watcher 存到该属性的 dep 依赖容器中
  • 当这个属性发生变化时,会出发改属性的 set 的方法,set 函数中会把 dep 存的依赖都执行

到此这篇关于实现一个简单得数据响应系统的文章就介绍到这了,更多相关数据响应系统内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
javascript与jquery中跳出循环的区别总结
Nov 04 Javascript
jQuery中hasClass()方法用法实例
Jan 06 Javascript
angular简介和其特点介绍
Jan 29 Javascript
jQuery循环动画与获取组件尺寸的方法
Feb 02 Javascript
详解jQuery简单的表格应用
Dec 16 Javascript
react-native中ListView组件点击跳转的方法示例
Sep 30 Javascript
jQuery 实现左右两侧菜单添加、移除功能
Jan 02 jQuery
浅谈微信小程序之官方UI框架we-ui使用教程
Aug 20 Javascript
使用JS实现导航切换时高亮显示的示例讲解
Aug 22 Javascript
VUE 组件转换为微信小程序组件的方法
Nov 06 Javascript
vue el-table实现行内编辑功能
Dec 11 Javascript
js实现带有动画的返回顶部
Aug 09 Javascript
JavaScript函数柯里化
Nov 07 #Javascript
JS数组去重详情
Nov 07 #Javascript
手写实现JS中的new
Nov 07 #Javascript
用JS写一个发布订阅模式
Nov 07 #Javascript
浅谈JavaScript浅拷贝和深拷贝
JavaScript严格模式不支持八进制的问题讲解
Javascript使用integrity属性进行安全验证
Nov 07 #Javascript
You might like
java EJB 加密与解密原理的一个例子
2008/01/11 PHP
PHP微信开发之查询城市天气
2016/06/23 PHP
PHP 匿名函数与注意事项详细介绍
2016/11/26 PHP
Laravel中七个非常有用但很少人知道的Carbon方法
2017/09/21 PHP
网页图片延时加载的js代码
2010/04/22 Javascript
jQuery实现瀑布流的取巧做法分享
2015/01/12 Javascript
javascript中html字符串转化为jquery dom对象的方法
2015/08/27 Javascript
JS+CSS实现仿雅虎另类滑动门切换效果
2015/10/13 Javascript
jQuery中inArray方法注意事项分析
2016/01/25 Javascript
JavaScript实现打开链接页面的方式汇总
2016/06/02 Javascript
通过javascript进行UTF-8编码的实现方法
2016/06/27 Javascript
Vue通过input筛选数据
2020/10/26 Javascript
自定义vue组件发布到npm的方法
2018/05/09 Javascript
jQuery.parseJSON()函数详解
2019/02/28 jQuery
微信小程序picker组件关于objectArray数据类型的绑定方法
2019/03/13 Javascript
Python制作CSDN免积分下载器
2015/03/10 Python
Anaconda入门使用总结
2018/04/05 Python
Python3中的json模块使用详解
2018/05/05 Python
Python 一句话生成字母表的方法
2019/01/02 Python
解决win7操作系统Python3.7.1安装后启动提示缺少.dll文件问题
2019/07/15 Python
对python中 math模块下 atan 和 atan2的区别详解
2020/01/17 Python
python图形开发GUI库pyqt5的基本使用方法详解
2020/02/14 Python
Python3爬虫中Selenium的用法详解
2020/07/10 Python
HTML5的hidden属性兼容老浏览器的方法
2014/04/23 HTML / CSS
长曲棍球装备:Lacrosse Monkey
2020/12/02 全球购物
英语道歉信范文
2014/01/09 职场文书
广告业务员岗位职责
2014/02/06 职场文书
党的群众路线教育实践活动学习心得体会
2014/03/03 职场文书
三好学生先进事迹材料
2014/08/28 职场文书
四风问题班子对照检查材料
2014/09/27 职场文书
民主评议党员登记表自我评价
2014/10/20 职场文书
2014年健康教育工作总结
2014/11/20 职场文书
家属联谊会致辞
2015/07/31 职场文书
工作一年自我鉴定
2019/06/20 职场文书
浅谈python数据类型及其操作
2021/05/25 Python
教你怎么用PyCharm为同一服务器配置多个python解释器
2021/05/31 Python