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


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代码
Jul 01 Javascript
Javascript继承(上)——对象构建介绍
Nov 08 Javascript
javascript中类的定义方式详解(四种方式)
Dec 22 Javascript
原生JavaScript制作微博发布面板效果
Mar 11 Javascript
jQuery Mobile和HTML5开发App推广注册页
Nov 07 Javascript
利用jquery实现下拉框的禁用与启用
Dec 07 Javascript
AngularJS实现网站换肤实例
Feb 19 Javascript
完美解决node.js中使用https请求报CERT_UNTRUSTED的问题
Jan 08 Javascript
JavaScript获取ul中li个数的方法
Feb 13 Javascript
详解使用fetch发送post请求时的参数处理
Apr 05 Javascript
将jquery.qqFace.js表情转换成微信的字符码
Dec 01 jQuery
JavaScript中的几种继承方法示例
Dec 06 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
Oracle 常见问题解答
2006/10/09 PHP
刚才在简化php的库,结果发现很多东西
2006/12/31 PHP
深入PHP内存相关的功能特性详解
2013/06/08 PHP
Yii2学习笔记之汉化yii设置表单的描述(属性标签attributeLabels)
2017/02/07 PHP
PHP的RSA加密解密方法以及开发接口使用
2018/02/11 PHP
效率高的Javscript字符串替换函数的benchmark
2008/08/02 Javascript
解析Javascript小括号“()”的多义性
2013/12/03 Javascript
js 限制input只能输入数字、字母和汉字等等
2013/12/18 Javascript
JavaScript原型链示例分享
2014/01/26 Javascript
jQuery/CSS3图片特效插件整理推荐
2014/12/07 Javascript
AngularJs Javascript MVC 框架
2016/06/20 Javascript
jQuery Validation Engine验证控件调用外部函数验证的方法
2017/01/18 Javascript
利用Vue.js框架实现火车票查询系统(附源码)
2017/02/27 Javascript
JavaScript中最常用的10种代码简写技巧总结
2017/06/28 Javascript
p5.js绘制旋转的正方形
2019/10/23 Javascript
小程序实现长按保存图片的方法
2019/12/31 Javascript
Vue中key的作用示例代码详解
2020/06/10 Javascript
vue实现公告栏文字上下滚动效果的示例代码
2020/06/16 Javascript
[04:09]显微镜下的DOTA2第十二期—NaVi美如画的团战
2014/06/23 DOTA
python实现批量改文件名称的方法
2015/05/25 Python
使用Python简单的实现树莓派的WEB控制
2016/02/18 Python
Python 实现某个功能每隔一段时间被执行一次的功能方法
2018/10/14 Python
python3中property使用方法详解
2019/04/23 Python
浅谈Python中函数的定义及其调用方法
2019/07/19 Python
python实现npy格式文件转换为txt文件操作
2020/07/01 Python
HTML5 input placeholder 颜色修改示例
2014/05/30 HTML / CSS
结婚邀请函范文
2014/01/14 职场文书
大学活动邀请函
2014/01/28 职场文书
关于期中考试的反思
2014/02/02 职场文书
小学教师自我鉴定范文
2014/03/20 职场文书
放弃继承权公证书
2015/01/23 职场文书
餐饮食品安全责任书
2015/01/29 职场文书
2015年小学开学寄语
2015/02/27 职场文书
法律意见书范本
2015/06/04 职场文书
OpenCV-Python实现人脸磨皮算法
2021/06/07 Python
Android RecyclerView实现九宫格效果
2022/06/28 Java/Android