2023 vue2的响应式原理 通俗易懂!

1、vue2的响应式原理?

1.1、前言

Object.defineProperty+依赖追踪

在Vue实例化过程中,会递归地将每个数据对象属性转换为getter/setter,并维护一个依赖收集器(Dep)每个属性都有一个关联的watcher,当数据发生变化时watcher被通知更新视图

Vue 2.x 实现响应式数据:

{{ message }}

const app = new Vue({
  el: '#app',
  data: {
    message: 'Hello, Vue!'
  },
  methods: {
    updateMessage() {
      this.message = 'Hello, World!';
    }
  }
});

vue实例化时,会将message属性转换为 getter/setter,并添加到依赖收集器中。当属性值变化时,依赖收集器通知相关的watcher更新视图。

1.2、如何转为getter/setter

在 Vue2.X 中,可以使用 Object.defineProperty() 将属性转换为 getter/setter。这个方法接收三个参数:对象属性名称和一个描述符对象

示例代码:

/*
 * @Description:
 * @Author: muge
 * @Date: 2022-10-03 12:01:03
 * @LastEditors: muge
 * @LastEditTime: 2023-05-20 14:33:35
 */
var obj = {}; // 创建一个空对象
// 定义一个属性 name,并将其转换为 getter/setter
Object.defineProperty(obj, "name", {
  get: function () {
    console.log("获取 name 属性");
    return this._name;
  },
  set: function (value) {
    console.log("设置 name 属性为", value);
    this._name = value;
  },
});
// 使用属性
obj.name = "muge"; // 调用 setter
console.log(obj.name); // 调用 getter,打印 'muge'

我们将 obj 对象的 name 属性转换为 getter/setter。当获取 name 属性时,get() 方法会被调用。当设置 name 属性时,set() 方法会被调用。

1.3、为什么Vue 2.x只能追踪对象属性的变化,无法直接追踪数组的变化?

1.3.1、前言

因为数组的属性名是数字,内置方法(如 push、pop、splice 等)可以改变数组长度或元素值等。导致无法对数组进行有效监听,使得数组的数据变化无法自动触发视图更新。

如 push 方法添加元素,可以改变数组的长度,但不会触发对应下标的 setter 方法

1.3.2、解决

使用Vue 提供的$set$delete 等数组方法。

你可能感兴趣的:(vue.js,javascript,前端)