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


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 相关文章推荐
Highslide.js是一款基于js实现的网页中图片展示插件
Mar 30 Javascript
js面向对象设计用{}好还是function(){}好(构造函数)
Oct 23 Javascript
读取input:file的路径并显示本地图片的方法
Sep 23 Javascript
javaScript对文字按照拼音排序实现代码
Dec 27 Javascript
使用jQuery将多条数据插入模态框的实现代码
Oct 08 Javascript
AngularJS ng-app 指令实例详解
Jul 30 Javascript
AngularJS基于ui-route实现深层路由的方法【路由嵌套】
Dec 14 Javascript
BootStrap Fileinput插件和Bootstrap table表格插件相结合实现文件上传、预览、提交的导入Excel数据操作步骤
Aug 07 Javascript
layui layer select 选择被遮挡的解决方法
Sep 21 Javascript
基于Vue sessionStorage实现保留搜索框搜索内容
Jun 01 Javascript
Laravel 如何在blade文件中使用Vue组件的示例代码
Jun 28 Javascript
微信小程序实现自定义底部导航
Nov 18 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
Syphon 使用方法
2021/03/03 冲泡冲煮
用PHP调用数据库的存贮过程!
2006/10/09 PHP
PHP下利用shell后台运行PHP脚本,并获取该脚本的Process ID的代码
2011/09/19 PHP
php调用c接口无错版介绍
2014/03/11 PHP
PHP abstract 抽象类定义与用法示例
2018/05/29 PHP
PHP调用全国天气预报数据接口查询天气示例
2019/02/20 PHP
php设计模式之职责链模式实例分析【星际争霸游戏案例】
2020/03/27 PHP
js iframe跨域访问(同主域/非同主域)分别深入介绍
2013/01/24 Javascript
js showModalDialog参数的使用详解
2014/01/07 Javascript
jquery五角星评分插件示例分享
2014/02/21 Javascript
深入理解jquery中的each用法
2016/12/14 Javascript
js实现图片切换(动画版)
2016/12/25 Javascript
Angular2.js实现表单验证详解
2017/06/23 Javascript
vue实现点击选中,其他的不选中方法
2018/09/05 Javascript
JS实现集合的交集、补集、差集、去重运算示例【ES5与ES6写法】
2019/02/18 Javascript
jquery选择器和属性对象的操作实例分析
2020/01/10 jQuery
Echarts在Taro微信小程序开发中的踩坑记录
2020/11/09 Javascript
python 实现文件的递归拷贝实现代码
2012/08/02 Python
Python中条件判断语句的简单使用方法
2015/08/21 Python
Python实现DDos攻击实例详解
2019/02/02 Python
Python3.4学习笔记之常用操作符,条件分支和循环用法示例
2019/03/01 Python
python如何解析配置文件并应用到项目中
2019/06/27 Python
基于Pytorch SSD模型分析
2020/02/18 Python
Pycharm中切换pytorch的环境和配置的教程详解
2020/03/13 Python
CSS3 特效范例整理
2011/08/22 HTML / CSS
函数只定义了一次, 调用了一次, 但编译器提示非法重定义了-什么问题?
2014/10/03 面试题
金士达面试非笔试
2012/03/14 面试题
在DELPHI中调用存储过程和使用内嵌SQL哪种方式更好
2016/11/22 面试题
汽车装潢店创业计划书范文
2014/02/05 职场文书
农村党员一句话承诺
2014/05/30 职场文书
销售员工作检讨书(推荐篇)
2014/10/18 职场文书
2015年简历自我评价范文
2015/03/11 职场文书
2015年度电厂个人工作总结
2015/05/13 职场文书
采购部年度工作总结
2015/08/13 职场文书
公司新员工欢迎词
2015/09/30 职场文书
MySQL库表太大怎么办? 数据库分库分表项目实践
2022/04/11 MySQL