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


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 相关文章推荐
DWR实现模拟Google搜索效果实现原理及代码
Jan 30 Javascript
JS实现网页右侧带动画效果的伸缩窗口代码
Oct 29 Javascript
前端编码规范(3)JavaScript 开发规范
Jan 21 Javascript
浅谈js中startsWith 函数不能在任何浏览器兼容的问题
Mar 01 Javascript
整理关于Bootstrap表单的慕课笔记
Mar 29 Javascript
jQuery操作DOM_动力节点Java学院整理
Jul 04 jQuery
利用jsonp与代理服务器方案解决跨域问题
Sep 14 Javascript
Laravel整合Bootstrap 4的完整方案(推荐)
Jan 25 Javascript
React props和state属性的具体使用方法
Apr 12 Javascript
讲解vue-router之命名路由和命名视图
May 28 Javascript
Vue + Node.js + MongoDB图片上传组件实现图片预览和删除功能详解
Apr 29 Javascript
Javascript数组及类数组相关原理详解
Oct 29 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
比特率,大家看看这个就不用收音机音质去比MP3音质了
2021/03/01 无线电
PHP 八种基本的数据类型小结
2011/06/01 PHP
Centos7安装swoole扩展操作示例
2020/03/26 PHP
简洁短小的 JavaScript IE 浏览器判定代码
2010/03/21 Javascript
jQuery 网易相册鼠标移动显示隐藏效果实现代码
2013/03/31 Javascript
关于JavaScript中的关联数组分析
2013/04/09 Javascript
jQuery打印图片pdf、txt示例代码
2014/07/22 Javascript
基于BootStrap栅格栏系统完成网站底部版权信息区
2016/12/23 Javascript
bootstrap输入框组使用方法
2017/02/07 Javascript
JS实现的简单拖拽功能示例
2017/03/13 Javascript
Vuejs实现购物车功能
2017/11/05 Javascript
详解vuex状态管理模式
2018/11/01 Javascript
JS立即执行函数功能与用法分析
2019/01/15 Javascript
微信小程序实现下拉框功能
2019/07/16 Javascript
微信小程序日历插件代码实例
2019/12/04 Javascript
使用 Vue-TCB 快速在 Vue 应用中接入云开发的方法
2020/02/10 Javascript
前端深入理解Typescript泛型概念
2020/03/09 Javascript
[00:33]2016完美“圣”典风云人物:Sccc宣传片
2016/12/03 DOTA
布同 Python中文问题解决方法(总结了多位前人经验,初学者必看)
2011/03/13 Python
python连接mongodb操作数据示例(mongodb数据库配置类)
2013/12/31 Python
Python网络爬虫项目:内容提取器的定义
2016/10/25 Python
Tensorflow简单验证码识别应用
2017/05/25 Python
Python编程之黑板上排列组合,你舍得解开吗
2017/10/30 Python
Python中遍历列表的方法总结
2019/06/27 Python
Python3.7 pyodbc完美配置访问access数据库
2019/10/03 Python
python小项目之五子棋游戏
2019/12/26 Python
Python连接字符串过程详解
2020/01/06 Python
python爬虫容易学吗
2020/06/02 Python
html5实现的便签特效(实战分享)
2013/11/29 HTML / CSS
What's the difference between an interface and abstract class? (接口与抽象类有什么区别)
2012/10/29 面试题
内蒙古鄂尔多斯市市长寄语
2014/04/10 职场文书
小学国庆节活动方案策划书
2014/09/16 职场文书
不尊敬老师的检讨书
2014/12/21 职场文书
校园安全主题班会
2015/08/12 职场文书
小学三年级作文之写景
2019/11/05 职场文书
mysql 8.0.24版本安装配置方法图文教程
2021/05/12 MySQL