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


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 - 如何引入js代码
Mar 09 Javascript
最新优化收藏到网摘代码(digg,diigo)
Feb 07 Javascript
前端开发的开始---基于面向对象的Ajax类
Sep 17 Javascript
jquery.combobox中文api和例子,修复了上面的小bug
Mar 28 Javascript
jquery对dom的操作常用方法整理
Jun 25 Javascript
使用Meteor配合Node.js编写实时聊天应用的范例
Jun 23 Javascript
JQuery操作textarea,input,select,checkbox方法
Sep 02 Javascript
AngularJs上传前预览图片的实例代码
Jan 20 Javascript
webpack学习教程之publicPath路径问题详解
Jun 17 Javascript
Vue使用高德地图搭建实时公交应用功能(地图 + 附近站点+线路详情 + 输入提示+换乘详情)
May 16 Javascript
JavaScript中变量提升与函数提升经典实例分析
Jul 26 Javascript
vue.js表单验证插件(vee-validate)的使用教程详解
May 23 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
php的dl函数用法实例
2014/11/06 PHP
PHP从FLV文件获取视频预览图的方法
2015/03/12 PHP
两种php去除二维数组的重复项方法
2015/11/04 PHP
php的socket编程详解
2016/11/20 PHP
PHP合并数组的2种方法小结
2016/11/24 PHP
Javascript 写的简单进度条控件
2008/01/22 Javascript
jQuery EasyUI NumberBox(数字框)的用法
2010/07/08 Javascript
利用jQuery接受和处理xml数据的代码(.net)
2011/03/28 Javascript
Jquery跨浏览器文本复制插件Zero Clipboard的使用方法
2016/02/28 Javascript
Bootstrap嵌入jqGrid,使你的table牛逼起来
2016/05/05 Javascript
使用ReactJS实现tab页切换、菜单栏切换、手风琴切换和进度条效果
2016/10/17 Javascript
javascript基础知识讲解
2017/01/11 Javascript
微信小程序 动态的设置图片的高度和宽度详解及实例代码
2017/02/24 Javascript
原生JS实现循环Nodelist Dom列表的4种方式示例
2018/02/11 Javascript
详解基于Node.js的HTTP/2 Server实践
2018/05/31 Javascript
微信小程序实现城市列表选择
2018/06/05 Javascript
详解微信小程序缓存--缓存时效性
2019/05/02 Javascript
微信小程序实现打开并下载服务器上面的pdf文件到手机
2019/09/20 Javascript
微信小程序国际化探索实现(附源码地址)
2020/05/20 Javascript
[00:12]2018DOTA2亚洲邀请赛 Sccc亮相SOLO赛,今年他又会有什么样的战绩?
2018/04/06 DOTA
python实现倒计时的示例
2014/02/14 Python
Python实现端口复用实例代码
2014/07/03 Python
python网络编程之文件下载实例分析
2015/05/20 Python
Python中文字符串截取问题
2015/06/15 Python
在Django的URLconf中进行函数导入的方法
2015/07/18 Python
简单讲解Python中的字符串与字符串的输入输出
2016/03/13 Python
Python2和Python3的共存和切换使用
2019/04/12 Python
pytorch 在网络中添加可训练参数,修改预训练权重文件的方法
2019/08/17 Python
利用Python绘制Jazz网络图的例子
2019/11/21 Python
python基于pygame实现飞机大作战小游戏
2020/11/19 Python
css3学习心得分享
2013/08/19 HTML / CSS
会计与审计专业大专生求职信
2013/10/03 职场文书
期中考试反思800字
2014/05/01 职场文书
放飞梦想演讲稿600字
2014/08/26 职场文书
2019脱贫攻坚工作总结报告范本!
2019/08/06 职场文书
海贼王十大逆天果实 魂魂果实上榜,岩浆果实攻击力最强
2022/03/18 日漫