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


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日期时间格式化函数分享
May 05 Javascript
JavaScript中使用stopPropagation函数停止事件传播例子
Aug 27 Javascript
bootstrap模态框垂直居中效果
Dec 03 Javascript
jQuery动态生成不规则表格(前后端)
Feb 21 Javascript
JavaScript实现动态增删表格的方法
Mar 09 Javascript
Vue2.0利用 v-model 实现组件props双向绑定的优美解决方案
Mar 13 Javascript
实现单层json按照key字母顺序排序的示例
Dec 06 Javascript
使用D3.js构建实时图形的示例代码
Aug 28 Javascript
vue+egg+jwt实现登录验证的示例代码
May 18 Javascript
Vue中使用better-scroll实现轮播图组件
Mar 07 Javascript
vue实现评价星星功能
Jun 30 Javascript
vue调用本地摄像头实现拍照功能
Aug 14 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异常:Parse error: syntax error, unexpected T_ENCAPSED_AND_WHITESPACE  eval()'d code error
2011/05/19 PHP
简单说说PHP优化那些事(经验分享)
2014/11/27 PHP
php框架CodeIgniter使用redis的方法分析
2018/04/13 PHP
Laravel5.5 视图 - 创建视图和数据传递示例
2019/10/21 PHP
解决php用mysql方式连接数据库出现Deprecated报错问题
2019/12/25 PHP
在IE下:float属性会影响offsetTop的取值
2006/12/22 Javascript
JavaScript对象链式操作代码(jquery)
2010/07/04 Javascript
JavaScript继承方式实例
2010/10/29 Javascript
File, FileReader 和 Ajax 文件上传实例分析(php)
2011/04/27 Javascript
通过js动态操作table(新增,删除相关列信息)
2012/05/23 Javascript
页面js遇到乱码问题的解决方法是和无法转码的情况
2014/04/30 Javascript
nodejs实现黑名单中间件设计
2014/06/17 NodeJs
Js+php实现异步拖拽上传文件
2015/06/23 Javascript
Javascript验证Visa和MasterCard信用卡号的方法
2015/07/27 Javascript
javascript实现鼠标放上后下边对应内容变换的效果
2015/08/06 Javascript
基于jQuey实现鼠标滑过变色(整行变色)
2015/12/07 Javascript
js随机生成26个大小写字母
2016/02/12 Javascript
JavaScript实现Fly Bird小游戏
2016/12/15 Javascript
vue省市区三联动下拉选择组件的实现
2017/04/28 Javascript
jQuery实现可拖动进度条实例代码
2017/06/21 jQuery
vue移动端UI框架实现QQ侧边菜单组件
2018/03/09 Javascript
JS跨域请求的问题解析
2018/12/03 Javascript
详解Vue.js v-for不支持IE9的解决方法
2018/12/29 Javascript
微信小程序实现翻牌抽奖动画
2020/09/21 Javascript
深入理解 Python 中的多线程 新手必看
2016/11/20 Python
Python使用微信SDK实现的微信支付功能示例
2017/06/30 Python
利用python将pdf输出为txt的实例讲解
2018/04/23 Python
Django通过json格式收集主机信息
2020/05/29 Python
使用tensorflow根据输入更改tensor shape
2020/06/23 Python
html特殊符号示例 html特殊字符编码对照表
2014/01/14 HTML / CSS
美国首屈一指的高品质珠宝设计师和零售商:Allurez
2018/01/23 全球购物
贝玲妃英国官网:Benefit英国
2018/02/03 全球购物
电子信息毕业生自荐信
2013/11/16 职场文书
化妆品活动策划方案
2014/05/23 职场文书
新党章心得体会
2014/09/04 职场文书
2014年学校安全工作总结
2014/11/13 职场文书