欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

VUE 2.x的响应式原理模型

程序员文章站 2022-07-02 19:15:10
123...

先把结果展示出来:(整个实现的源代码在下面,拿去试试)

VUE 2.x的响应式原理模型
VUE 2.x的响应式原理模型

<!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>
    <script>
      let ARRAY_METHODS = [
        "push",
        "pop",
        "shift",
        "unshift",
        "reverse",
        "sort",
        "splice",
      ];

      //   此方法仍然无法解决操作数组长度length属性的响应式问题 vue3的proxy 可以解决  替代方法:splice(0)
      let array_methods = Object.create(Array.prototype);
      ARRAY_METHODS.forEach((method) => {
        array_methods[method] = function () {
          console.log(`当前正在使用的是拦截后的方法:${method}`);
          for (var i = 0; i < arguments.length; i++) {
            reactify(arguments[i]);
          }
          let res = Array.prototype[method].apply(this, arguments);
          return res;
        };
      });

      // 劫持数据
      function defineReactive(target, key, value, enumerable) {
        Object.defineProperty(target, key, {
          configurable: true,
          enumerable: !!enumerable,
          get() {
            console.log(`读取${key}属性当前值为${value}`);
            return value;
          },
          set(newVal) {
            console.log(`设置${key}属性,改为:${newVal}`);
            value = newVal;
          },
        });
      }

      //  数据响应式化处理
      function reactify(o) {
        let keys = Object.keys(o);
        for (var i = 0; i < keys.length; i++) {
          let key = keys[i];
          let val = o[key];
          if (Array.isArray(o[key])) {
            val.__proto__ = array_methods; // 使用前文中的js劫持策略且只重写需要要改为响应式数组的原型方法 
            for (var j = 0; j < val.length; j++) {
              reactify(val[j]);
            }
          } else {
            defineReactive(o, key, val, true); // 数据劫持并响应式处理
          }
        }
      }

      //   数据源
      let data = {
        name: "zachary",
        age: 18,
        hobits: [{ title: "爬山" }, { title: "游泳" }, { title: "电子游戏" }],
      };
      reactify(data);
    </script>
  </body>
</html>

本文地址:https://blog.csdn.net/MrZachary_zlc/article/details/112860179

相关标签: vue源码