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


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 EXCEL 操作类代码
Jul 30 Javascript
基于JQuery的asp.net树实现代码
Nov 30 Javascript
吐槽一下我所了解的Node.js
Oct 08 Javascript
AngularJS基础知识笔记之过滤器
May 10 Javascript
在Node.js应用中读写Redis数据库的简单方法
Jun 30 Javascript
vue权限路由实现的方法示例总结
Jul 29 Javascript
JS实现简单的点赞与踩功能示例
Dec 05 Javascript
express express-session的使用小结
Dec 12 Javascript
js如何获取图片url的Blob值并预览示例代码
Mar 07 Javascript
vue-cli4使用全局less文件中的变量配置操作
Oct 21 Javascript
vue中如何自定义右键菜单详解
Dec 08 Vue.js
Vue OpenLayer测距功能的实现
Apr 20 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 数组和字符串互相转换实现方法
2013/03/26 PHP
php中smarty区域循环的方法
2015/06/11 PHP
PHP实现在线阅读PDF文件的方法
2015/06/23 PHP
PHPMailer发送邮件
2016/12/28 PHP
PHP中常见的密码处理方式和建议总结
2018/10/14 PHP
浅析PHP7的多进程及实例源码
2019/04/14 PHP
IE bug table元素的innerHTML
2010/01/11 Javascript
JS 对象介绍
2010/01/20 Javascript
Js 时间函数getYear()的使用问题探讨
2013/04/01 Javascript
jQuery提交多个表单的小例子
2013/06/30 Javascript
莱鸟介绍window.print()方法
2016/01/06 Javascript
JavaScript+html5 canvas实现本地截图教程
2020/04/16 Javascript
JavaScript位移运算符(无符号) &gt;&gt;&gt; 三个大于号 的使用方法详解
2016/03/31 Javascript
jquery实现数字输入框
2017/02/22 Javascript
vue路由嵌套的SPA实现步骤
2017/11/06 Javascript
Vue项目分环境打包的实现步骤
2018/04/02 Javascript
javascript标准库(js的标准内置对象)总结
2018/05/26 Javascript
8 个有用的JS技巧(推荐)
2019/07/03 Javascript
Vue 子组件与数据传递问题及注意事项
2019/07/11 Javascript
Python去除列表中重复元素的方法
2015/03/20 Python
pymongo实现多结果进行多列排序的方法
2015/05/16 Python
Python字典,函数,全局变量代码解析
2017/12/18 Python
python 中的list和array的不同之处及转换问题
2018/03/13 Python
python如何在列表、字典中筛选数据
2018/03/19 Python
numpy.ndarray 交换多维数组(矩阵)的行/列方法
2018/08/02 Python
Django ORM 常用字段与不常用字段汇总
2019/08/09 Python
python rsync服务器之间文件夹同步脚本
2019/08/29 Python
python多线程高级锁condition简单用法示例
2019/11/07 Python
手把手教你如何用Pycharm2020.1.1配置远程连接的详细步骤
2020/08/07 Python
Python jieba库分词模式实例用法
2021/01/13 Python
H5 video poster属性设置视频封面的方法
2020/05/25 HTML / CSS
COS美国官网:知名服装品牌
2019/04/08 全球购物
Hanky Panky官方网站:内衣和睡衣
2019/07/25 全球购物
违反学校规定检讨书
2014/01/18 职场文书
标准的毕业生自荐信
2014/04/20 职场文书
博士导师推荐信
2015/03/25 职场文书