vue响应式 底层原理

本文深入探讨Vue框架的响应式机制,解析数据变化如何驱动视图更新,涉及数据劫持、依赖收集等核心概念。
摘要由CSDN通过智能技术生成

页面端

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    订阅发布1<span class="box1"></span>
    订阅发布2<span class="box2"></span>
    <script src="index.js"></script>
    <script>
        let dataObj = {};
        dataHijack({
            data: dataObj,
            tag: "view1",
            dataKey: "one",
            selector: ".box1"
        });
        dataHijack({
            data: dataObj,
            tag: "view2",
            dataKey: "two",
            selector: ".box2"
        });

        dataObj.one = "一笑置之";
        dataObj.two = "爱丽丝";
    </script>
</body>

</html>

JS代码

//当数据改变时,我们要进行通知
//只有订阅这个数据 才会通知

//订阅器模型
let Dep = {
  clientList: {}, //定义List列表用来存放消息 干货:为什么用对象来存储 → 深拷贝,浅拷贝
  //如果用数组,去数组里取值就必须用key去取值,相当于深拷贝,深拷贝 复杂度与消耗性能比浅拷贝多
  //如果用对象  就避免了这层 查找更快
  listen: function (key, fn) {
    //key是唯一的 可以有多个函数
    // if(!this.clientList[key]){//判断key是否存在 若不存在 给其预留空间
    //     this.clientList[key]=[]
    // }
    // this.clientList[key].push(fn);

    //vue源码写法 短路运算符
    (this.clientList[key] || (this.clientList[key] = [])).push(fn); //判断key是否存在 不存在 预留空间 且用push方法将函数fn推入
  },
  //发布消息
  trigger: function () {
    //类数组转化未数组
    let key = Array.prototype.shift.call(arguments), //需要理解
      fns = this.clientList[key];
    if (!fns || fns.length === 0) {
      //判断是否存在fns这个值
      return false;
    }
    //vue源码写法  不会有终止条件
    for (let i = 0,fn; fn = fns[i++];) {
      fn.apply(this, arguments); //改变指针
    }
  },
};

//发布订阅模式+数据劫持
//劫持方法

let dataHijack = function ({ data, tag, dataKey, selector }) {
  //data:需要劫持的数据 tag:具体的对象 datakey:唯一的值 ,selector:选择的元素
  let value = "",
    el = document.querySelector(selector);
  //数据劫持
  Object.defineProperty(data, dataKey, {
    get: function () {
      console.log("我获取到了值");
      return value;
    },
    set: function (newValue) {
      console.log("我设置了值"); //当设置了新的值 我们要进行通知 订阅方 更改
      //通知订阅者
      value = newValue; //新旧值的替换
      Dep.trigger(tag, newValue); //关键点
    },
  });
  //添加订阅者
  Dep.listen(tag, function (text) {
    //关键点
    el.innerHTML = text;
  });
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值