IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> vue源码解析 002 双向数据绑定时 数据类型为数组的处理 -> 正文阅读

[JavaScript知识库]vue源码解析 002 双向数据绑定时 数据类型为数组的处理

为什么要重写数组方法触发视图更新

如果数据类型是对象的时候,可以使用object.defineProperty实现对数据的监监听

但是当数据类型是数组的时候,如果有成千上万条数据呢,每个数据都进行监听,就太消耗性能了,所有我们重写了改变原数组的方法,在调用这些方法时触发更新

数据监听的index.js文件

import { arrayMethods } from "./array";

class Observer {
  constructor(value) {

    console.log("value10000",value)
    //需要对这个value属性重新定义
    //可能是对象,可能是数组
    // value.__ob__ = this//给每个属性
    Object.defineProperty(value, "__ob__", {
      value: this,
      enumerable: false, //表示不能枚举
      configurable: false, //表示不能删除
    });
    if (Array.isArray(value)) {
      console.log("55555555555555")
      //数组不用defineProperty来进行代理,性能不好
      // push,shift,unshift,reverse,sort 将这方法重写,增加更新逻辑
      value.__proto__ = arrayMethods; //当是数组时,改写方法为自己重写后的方法

      this.observeArray(value); //原有数组中的对象  Object.freeze()
    } else {
      console.log("6666666666666666")
      this.walk(value);
    }
  }
  observeArray(value) {
    console.log("0000",value)
    for (let i = 0; i < value.length; i++) {
      const ele = value[i];
      observe(ele);
    }
  }
  walk(data) {
    // 将对象中的所有key,重新用defineProperty 定义成响应式的

    // 数组处理 如果数组也拦截 会十分浪费性能
    Object.keys(data).forEach((key) => {
      defineReactive(data, key, data[key]);
    });
  }
}

export function defineReactive(data, key, value) {
  // value 可能也是一个对象
  /**
   * vue2中数据嵌套不要过深  过深浪费性能
   *
   *
   *
   *
   */
  observe(value); //对结果递归拦截
  Object.defineProperty(data, key, {
    get() {
      return value;
    },
    set(newValue) {
      if (newValue === value) {
        return;
      }
      observe(newValue); //如果用户设置的是一个对象,就继续将用户设置的对象变成响应式的
      value = newValue;
    },
  });
}

export function observe(data) {
  console.log("observedata",data)
  // 只对对象类型进行观测  非对象无法关测
  if (typeof data !== "object" || data == null) {
    return;
  }
  if (data.__ob__) {
    // 对象已经观测过了,防止循环引用
    return;
  }
  // 通过类来实现对对象的观测,类可以方便扩展,会产生实例
  console.log("observedata1111",data)
  return new Observer(data);
}

注解

  1. 当数据类型时object 类型并且 对象没有被观测过防止循环引用
  2. 需要判断数据是数组还是对象
    1. 如果是对象,就使用object.defineProperty将对象的key定义为响应式的
    2. 如果是数组,不能挂测所有的数据,因为数组数据太多消耗性能,所以我们选择重写数通过这些重写的方法触发视图更

数组处理的代码

//先要拿到数组原型上的方法
let oldArrayProtoMethods = Array.prototype;
// 不能直接改写数组方法,只有被vue控制的数组才需要改写

export let arrayMethods = Object.create(Array.prototype);

let methods = ["push", "pop", "shift", "unshift", "splice", "reverse", "sort"];
// 改边原数组
// concat slice 都不能改变原数组
methods.forEach((method) => {
  //AOP  切片编程
  arrayMethods[method] = function (...args) {
    //重写数组方法
    //更新视图
    //数组变化
    // todo····
    // 有可能用户新增的数据是对象格式也需要进行拦截

    let result = oldArrayProtoMethods[method].call(this, ...args);
    let inserted;
    switch (method) {
      case "push":
        inserted = args;
        break;
      case "unshift":
        inserted = args;
        break;
      case "splice":
        inserted = args.slice(2); //第三个参数才是需要新增的数据
      default:
        break;
    }
    console.log("数据更新");
    if (inserted) {
      this.__ob__.observeArray(inserted);
    }
    return result;
  };
});

注解

  1. 需要重写的方法是能够修改原数组的方法
  2. 若有有新增的数据,需要调用 Observer类的observeArray 重新观测新增的数据
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-06 23:09:18  更:2022-04-06 23:09:23 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:23:17-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码