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


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 getElementsByClassName 和js取地址栏参数
Jan 02 Javascript
判断用户的在线状态 onbeforeunload事件
Mar 05 Javascript
给jQuery方法添加回调函数一款插件的应用
Jan 21 Javascript
自定义右键属性覆盖浏览器默认右键行为实现代码
Feb 02 Javascript
location.href用法总结(最主要的)
Dec 27 Javascript
谈谈我对JavaScript原型和闭包系列理解(随手笔记9)
Dec 24 Javascript
JS获取和修改元素样式的实例代码
Aug 06 Javascript
利用vue + koa2 + mockjs模拟数据的方法教程
Nov 22 Javascript
Vue-cli Eslint在vscode里代码自动格式化的方法
Feb 23 Javascript
JavaScript判断日期时间差的实例代码
Mar 01 Javascript
Vue+Element-U实现分页显示效果
Nov 15 Javascript
如何理解Vue简单状态管理之store模式
May 15 Vue.js
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结合飞信 免费天气预报短信
2009/05/07 PHP
Centos6.5和Centos7 php环境搭建方法
2016/05/27 PHP
PHP基于SPL实现的迭代器模式示例
2018/04/22 PHP
jQuery实战之品牌展示列表效果
2011/04/10 Javascript
通过jQuery源码学习javascript(一)
2012/12/27 Javascript
javascript 实现 秒杀,团购 倒计时展示的记录 分享
2013/07/12 Javascript
jquery选择器之基本过滤选择器详解
2014/01/27 Javascript
Javascript访问器属性实例分析
2014/12/30 Javascript
html的DOM中document对象forms集合用法实例
2015/01/21 Javascript
bootstrap警告框使用方法解析
2017/01/13 Javascript
JS中绑定事件顺序(事件冒泡与事件捕获区别)
2017/01/24 Javascript
JavaScript瀑布流布局实现代码
2017/05/06 Javascript
JS实现浏览上传文件的代码
2017/08/23 Javascript
javascript填充默认头像方法
2018/02/22 Javascript
微信小程序返回上一页传参并刷新过程解析
2019/12/13 Javascript
[38:32]DOTA2上海特级锦标赛A组资格赛#2 Secret VS EHOME第二局
2016/02/26 DOTA
python操作日期和时间的方法
2014/03/11 Python
Python操作MySQL数据库的方法
2018/06/20 Python
python利用requests库模拟post请求时json的使用教程
2018/12/07 Python
python读取目录下所有的jpg文件,并显示第一张图片的示例
2019/06/13 Python
Python Pandas 如何shuffle(打乱)数据
2019/07/30 Python
anaconda安装pytorch1.7.1和torchvision0.8.2的方法(亲测可用)
2021/02/01 Python
澳大利亚波西米亚风情网上商店:Czarina
2019/03/18 全球购物
美国美食礼品篮网站:Gourmet Gift Baskets
2019/12/15 全球购物
计算机求职信
2013/12/01 职场文书
关于毕业的广播稿
2014/01/10 职场文书
公司年会演讲稿范文
2014/01/11 职场文书
简历自我评价模版
2014/01/31 职场文书
初中语文教学反思
2014/02/02 职场文书
函授大学生自我鉴定
2014/02/05 职场文书
酒店员工职业生涯规划
2014/02/25 职场文书
学校班子个人对照检查材料思想汇报
2014/09/27 职场文书
小学感恩节活动策划方案
2014/10/06 职场文书
公司股东出资证明书
2014/11/01 职场文书
JavaScript阻止事件冒泡的方法
2021/12/06 Javascript
Redis数据同步之redis shake的实现方法
2022/04/21 Redis