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


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页面刷新与弹出窗口问题的解决方法
Mar 02 Javascript
node.js中的fs.writeSync方法使用说明
Dec 15 Javascript
在ASP.NET MVC项目中使用RequireJS库的用法示例
Feb 15 Javascript
原生js实现百叶窗效果及原理介绍
Apr 12 Javascript
js验证框架实现代码分享
May 18 Javascript
JS前端笔试题分析
Dec 19 Javascript
JavaScript表单验证的两种实现方法
Feb 11 Javascript
xmlplus组件设计系列之分隔框(DividedBox)(8)
May 02 Javascript
微信小程序 功能函数小结(手机号验证*、密码验证*、获取验证码*)
Dec 08 Javascript
JavaScript惰性载入函数实例分析
Mar 27 Javascript
Vue学习之组件用法实例详解
Jan 06 Javascript
原生js实现自定义消息提示框
Nov 19 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
如何给phpadmin一个保护
2006/10/09 PHP
PHP Yaf框架的简单安装使用教程(推荐)
2016/06/08 PHP
windows server 2008/2012安装php iis7 mysql环境搭建教程
2016/06/30 PHP
跟着JQuery API学Jquery 之二 属性
2010/04/09 Javascript
js有关元素内容操作小结
2011/12/20 Javascript
javascript firefox 自动加载iframe 自动调整高宽示例
2013/08/27 Javascript
Javascript中常见的校验如域名、手机、邮箱等等
2014/01/02 Javascript
javascript为下拉列表动态添加数据项
2014/05/23 Javascript
js 动态修改css文件的方法
2014/08/05 Javascript
用队列模拟jquery的动画算法实例
2015/01/20 Javascript
AngularJS中的API(接口)简单实现
2016/07/28 Javascript
js 将input框中的输入自动转化成半角大写(税号输入框)
2017/02/16 Javascript
微信小程序 本地数据读取实例
2017/04/27 Javascript
使用ES6语法重构React代码详解
2017/05/09 Javascript
原生JS实现不断变化的标签
2017/05/22 Javascript
详解vuex中mapState,mapGetters,mapMutations,mapActions的作用
2018/04/13 Javascript
js+css实现红包雨效果
2018/07/12 Javascript
jQuery实现点击自身以外区域关闭弹出层功能完整示例【改进版】
2018/07/31 jQuery
vue 2.8.2版本配置刚进入时候的默认页面方法
2018/09/21 Javascript
微信小程序实现多选功能
2018/11/04 Javascript
浅析Angular 实现一个repeat指令的方法
2019/07/21 Javascript
利用打码兔和超人打码自封装的打码类分享
2014/03/16 Python
Python实现两个list对应元素相减操作示例
2017/06/09 Python
Django中Model的使用方法教程
2018/03/07 Python
python3.7 的新特性详解
2019/07/25 Python
Python输出指定字符串的方法
2020/02/06 Python
为什么说python更适合树莓派编程
2020/07/20 Python
linux面试题参考答案(11)
2016/11/26 面试题
计算机专业大学生的自我评价
2013/11/14 职场文书
高中生毕业自我鉴定范文
2013/12/22 职场文书
一句话工作感言
2014/03/01 职场文书
施工安全责任书
2014/04/14 职场文书
家具公司总经理岗位职责
2014/07/08 职场文书
企业法人代表证明书
2014/09/27 职场文书
应聘教师求职信范文
2015/03/20 职场文书
2016年安康杯竞赛活动总结
2016/04/05 职场文书