首页 > 其他分享 >vue2响应式原理

vue2响应式原理

时间:2024-04-15 09:55:21浏览次数:23  
标签:function 依赖 vue2 raw dep depsMap 响应 key 原理

vue2响应式原理

class Dep {
  constructor() {
    // 依赖保存器
    this.subscribers = new Set();
  }
  // 收集依赖
  depend = () => {
    if (activeEffect) {
      this.subscribers.add(activeEffect);
    }
  };
  // 通知收集的依赖
  notify = () => {
    this.subscribers.forEach((effect) => {
      effect();
    });
  };
}
// 用于保存依赖数据结构.....
// weakmap 对于对象的引用为弱引用,当外界不再对存储对象进行引用,weakmap中存储的对象会被回收
const targetMap = new WeakMap();

function getDep(target, key) {
  // 根据target对象取出对应的map对象
  let depsMap = targetMap.get(target);
  if (!depsMap) {
    depsMap = new Map();
    targetMap.set(target, depsMap);
  }
  // 取出具体的dep对象
  let dep = depsMap.get(key);
  if (!dep) {
    dep = new Dep();
    depsMap.set(key, dep);
  }
  return dep;
}

// 响应式系统处理
function reactive(raw) {
  // 将传入对象的每个key都加入响应式系统中
  Object.keys(raw).forEach((key) => {
    const dep = getDep(raw, key);
    let value = raw[key];
    Object.defineProperty(raw, key, {
      get() {
        // 保存依赖
        dep.depend();
        return value;
      },
      set(newValue) {
        if (value !== newValue) {
          // raw[key] = newValue 会导致递归 这里设置以及返回的数据都是value 不能直接对raw操作 会导致死循环递归调用
          value = newValue;
          dep.notify();
        }
      }
    });
  });
  return raw;
}
// 用于临时保存 依赖函数
let activeEffect = null;

//
function watchEffect(effect) {
  // 保存依赖了变量的函数或其他表达式
  activeEffect = effect;
  // 默认 首次执行依赖,且必须执行,如果不执行,不触发get 无法添加依赖
  // 执行effect时就会访问对象属性,此时会把依赖的函数或表达式加入依赖收集中
  effect();
  // 恢复依赖收集,以便下次依赖添加
  activeEffect = null;
}

const info = reactive({ name: 'zdz', age: 18 });
const info1 = reactive({ height: 1.88 });

watchEffect(function () {
  console.log('watch1', info.name);
});
watchEffect(function () {
  console.log('watch2', info.age);
});

watchEffect(function () {
  console.log('watch3', info1.height);
});

info.name = 'newzdz';
info.age = 19;
info1.height = 2.0;

  • 当修改响应式对象中的值时,添加了监听的都会重新执行
  • 第一次watch1-3为首次添加监听执行,第二次为对象属性值变化响应式通知
    image.png

标签:function,依赖,vue2,raw,dep,depsMap,响应,key,原理
From: https://www.cnblogs.com/coderzdz/p/18135218

相关文章

  • 前言 —— CHATGPT原理与应用开发
    前言写作背景  从去年年底ChatGPT的发布以来,作为自然语言处理(naturallanguageprocessing,NLP)一线从业人员,我本人已经感受到了巨大压力,甚至觉得NLP工程师这个职位以后一定会消亡。当时在见识了ChatGPT的各种强大能力后,不少NLP一线从业人员很自然地就会想到,以后开发人员只要借......
  • 深入理解DES算法:原理、实现与应用
    title:深入理解DES算法:原理、实现与应用date:2024/4/1421:30:21updated:2024/4/1421:30:21tags:DES加密对称加密分组密码密钥管理S盒P盒安全性分析替代算法DES算法简介历史DES(DataEncryptionStandard)算法是由IBM研发,并于1977年被美国国家标准局(NBS,现NIST......
  • 18、应急响应
    1.应急响应1.1.国内相关组织https://www.cert.org.cnhttps://cnvd.org.cnhttps://www.anva.org.cnhttps://cverc.org.cn1.2.应急响应生命周期1.3.应急响应流程1.3.1.准备阶段分析资产风险明确信息系统网络与系统架构明确信息系统的管理人员明确信息系统的保护要求......
  • 万字长文深入理解Docker镜像分层原理、容器数据卷、网络通信架构(Docker系列第2章,共3章
    镜像分层的简单直观体现在执行dockerpull时,会发现多个Pullcomplete字样,就能体现分层,如果是一个文件,只会有一个Pullcomplete。dockerpullredisUsingdefaulttag:latestlatest:Pullingfromlibrary/redisa2abf6c4d29d:Alreadyexistsc7a4e4382001:Pullcomplete......
  • 幸福的原理
    一、塞利格曼幸福公式H=S+C+V持久的幸福=幸福的范围+生活条件+可控因素H代表的是持久的幸福,或者说幸福的持久度。为什么塞利格曼在定义“幸福”的时候要特别强调“持久”这个维度呢?这是因为只有持久的幸福才能反映幸福的真实水平。你可以把幸福想象成一条河流,持久......
  • vue 响应性代码demo
    <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metahttp-equiv="X-UA-Compatible"content="IE=edge"><metaname="viewport"content="width=device......
  • Mask实现原理(兼模板测试小结)
    前言虽然说网上已经有不少优秀的总结,但为了让知识停留在脑海里,我还是决定自己总结一份笔记。大概思路Mask会修改Graph组件的材质为StencilMaterial,该材质的作用是给每个不透明的像素标记,将标记结果存入模板缓冲区中。当子级UI进行模板测试时,如果通过就渲染,没通过就不渲染。......
  • redis自学(33)哨兵的作用和工作原理
    新建sentinel.conf文件。输入下面的内容  1是端口号2是sentinel声明的ip3是sentinel监控的master的ip和端口号,mymaster是集群的名字,也可以理解成给主节点起的名字,可以任意起名字。Slave的信息是从master得到的。2是选举master时的quorum值4是slave与master断开的最长超时......
  • VUE2.0版本学习笔记
    VUE2.0版本学习笔记脚手架安装npminstall-g@vue/clivuecreatevue2-practice#选择2.0版本如果执行中遇到错误,yarn的错误certificatehasexpired则执行yarncachecleanyarnconfigsetstrict-sslfalsecdvue2-practicenpmrunserve#初学者建议安装vsco......
  • Springboot2+vue2整合项目
    前端https://blog.csdn.net/m0_37613503/article/details/128961447数据库1.用户表CREATETABLE`x_user`(`id`int(11)NOTNULLAUTO_INCREMENT,`username`varchar(50)NOTNULL,`password`varchar(100)DEFAULTNULL,`email`varchar(50)DEFAULTNULL,`......