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


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 相关文章推荐
获取Javscript执行函数名称的方法
Dec 22 Javascript
JQuery入门——事件切换之toggle()方法应用介绍
Feb 05 Javascript
九种js弹出对话框的方法总结
Mar 12 Javascript
js去空格技巧分别去字符串前后、左右空格
Oct 21 Javascript
简体中文转换繁体中文(实现代码)
Dec 25 Javascript
IE8下jQuery改变png图片透明度时出现的黑边
Aug 30 Javascript
Angularjs中ng-repeat的简单实例
Aug 25 Javascript
JS监控关闭浏览器操作的实例详解
Sep 12 Javascript
微信小程序 input输入及动态设置按钮的实现
Oct 27 Javascript
微信小程序左滑删除实现代码实例
Sep 16 Javascript
vue实现多级菜单效果
Oct 19 Javascript
javascript设计模式 ? 简单工厂模式原理与应用实例分析
Apr 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
解决laravel groupBy 对查询结果进行分组出现的问题
2019/10/09 PHP
javascript使用正则控制input输入框允许输入的值方法大全
2014/06/19 Javascript
JavaScript获得表单target属性的方法
2015/04/02 Javascript
跟我学习javascript的this关键字
2020/05/28 Javascript
jQuery Validate表单验证深入学习
2015/12/18 Javascript
使用JQuery实现智能表单验证功能
2016/03/08 Javascript
JS实现pasteHTML兼容ie,firefox,chrome的方法
2016/06/22 Javascript
微信小程序实现图片轮播及文件上传
2017/04/07 Javascript
使用原生js写ajax实例(推荐)
2017/05/31 Javascript
Angular CLI在Angular项目中如何使用scss详解
2018/04/10 Javascript
jQuery实现输入框的放大和缩小功能示例
2018/07/21 jQuery
解决JavaScript layui 下拉框不显示的问题
2018/08/14 Javascript
antd组件Upload实现自己上传的实现示例
2018/12/18 Javascript
解决vuex刷新数据消失问题
2020/11/12 Javascript
[01:25]2015国际邀请赛最佳短片奖——斧王《拆塔英雄:天赋异禀》
2015/09/22 DOTA
Python使用urllib2获取网络资源实例讲解
2013/12/02 Python
Python实现树的先序、中序、后序排序算法示例
2017/06/23 Python
Python编程实现微信企业号文本消息推送功能示例
2017/08/21 Python
python使用PyCharm进行远程开发和调试
2017/11/02 Python
Django如何自定义model创建数据库索引的顺序
2019/06/20 Python
Python3自动生成MySQL数据字典的markdown文本的实现
2020/05/07 Python
Python爬虫新手入门之初学lxml库
2020/12/20 Python
详解CSS3中nth-child与nth-of-type的区别
2017/01/05 HTML / CSS
CSS3实现缺角矩形,折角矩形以及缺角边框
2019/12/20 HTML / CSS
移动端解决悬浮层(悬浮header、footer)会遮挡住内容的3种方法
2015/03/27 HTML / CSS
AmazeUI图片轮播效果的示例代码
2020/08/20 HTML / CSS
ProBikeKit澳大利亚:自行车套件,跑步和铁人三项装备
2016/11/30 全球购物
英国打印机墨水和碳粉商店:Printerinks
2017/06/30 全球购物
Shopee越南:东南亚与台湾电商平台
2019/02/03 全球购物
世界领先的豪华床上用品供应商之一:Bedeck Home
2019/03/18 全球购物
在线课程:Skillshare
2019/04/02 全球购物
项目经理任命书
2014/06/04 职场文书
2014中考励志标语
2014/06/05 职场文书
宣传委员竞选稿
2015/11/19 职场文书
MySQL创建管理KEY分区
2022/04/13 MySQL
mysql中关键词exists的用法实例详解
2022/06/10 MySQL