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


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 相关文章推荐
js图片轮播特效代码分享
Sep 07 Javascript
Bootstrap入门书籍之(四)菜单、按钮及导航
Feb 17 Javascript
详解JavaScript for循环中发送AJAX请求问题
Jun 23 Javascript
浅谈jquery点击label触发2次的问题
Jun 12 Javascript
JavaScript性能优化之函数节流(throttle)与函数去抖(debounce)
Aug 11 Javascript
js实现获取鼠标当前的位置
Dec 14 Javascript
node安装--linux下的快速安装教程
Mar 21 Javascript
js 毫秒转天时分秒的实例
Nov 17 Javascript
详解Vue前端对axios的封装和使用
Apr 01 Javascript
Angular8路由守卫原理和使用方法
Aug 29 Javascript
微信小程序列表时间戳转换实现过程解析
Oct 12 Javascript
js实现点击生成随机div
Jan 16 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
SONY ICF-F10中波修复记
2021/03/02 无线电
模拟OICQ的实现思路和核心程序(三)
2006/10/09 PHP
dedecms系统常用术语汇总
2007/04/03 PHP
并发下常见的加锁及锁的PHP具体实现代码
2010/10/12 PHP
Destoon实现多表查询示例
2014/08/21 PHP
laravel框架模板之公共模板、继承、包含实现方法分析
2019/08/30 PHP
jquery.validate使用攻略 第一部
2010/07/01 Javascript
js过滤HTML标签以及空格的思路及代码
2013/05/24 Javascript
使图片旋转的3种解决方案
2013/11/21 Javascript
jQuery 跨域访问解决原理案例详解
2016/07/09 Javascript
基于Bootstrap的Metronic框架实现页面链接收藏夹功能
2016/08/29 Javascript
jQuery Validate 数组 全部验证问题
2017/01/12 Javascript
vue.js实现请求数据的方法示例
2017/02/07 Javascript
element-ui多文件上传的实现示例
2019/04/10 Javascript
JS学习笔记之原型链和利用原型实现继承详解
2019/05/29 Javascript
vuex + keep-alive实现tab标签页面缓存功能
2019/10/17 Javascript
Jquery ajax书写方法代码实例解析
2020/06/12 jQuery
js实现圆形菜单选择器
2020/12/03 Javascript
[49:08]OpTic vs Serenity 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
[48:24]完美世界DOTA2联赛循环赛LBZS vs Forest 第一场 10月30日
2020/10/31 DOTA
python爬取淘宝商品销量信息
2018/11/16 Python
Python实现对字典分别按键(key)和值(value)进行排序的方法分析
2018/12/19 Python
python 绘制场景热力图的示例
2020/09/23 Python
如何利用python检测图片是否包含二维码
2020/10/15 Python
css3实现文字扫光渐变动画效果的示例
2017/11/07 HTML / CSS
购买美国制造的相框和画框架:Picture Frames
2018/08/14 全球购物
照片礼物和装饰:MyPhoto
2019/11/02 全球购物
机修工岗位职责
2013/11/24 职场文书
开办加工厂创业计划书
2014/01/03 职场文书
食品行业求职人的自我评价
2014/01/19 职场文书
幼儿教师工作感言
2014/02/14 职场文书
保护环境的标语
2014/06/09 职场文书
普通党员个人对照检查材料
2014/09/18 职场文书
2016年世界人口日宣传活动总结
2016/04/05 职场文书
导游词之铁岭象牙山
2019/12/06 职场文书
JavaScript中的宏任务和微任务详情
2021/11/27 Javascript