vue2的响应式数据原理

简介: `Object.defineProperty` 是 Vue 2 实现响应式数据的核心方法,通过定义 getter 和 setter 来追踪属性的变化。当访问或修改属性时,会触发相应的函数,从而实现数据的动态更新。本文介绍了该方法的基本用法、响应式原理及其简单实现,展示了如何通过监听属性变化来自动更新视图,体现了前端框架设计中的巧妙之处。

1.介绍Object.defineProperty

    vue2的响应式数据是依靠Object.defineProperty这个方法,用法如下:

const obj = {
username: "zz",
age: "zz",
};

// Object.defineProperty(对象名,对象键名,配置对象)
Object.defineProperty(obj, "username", {
  get() {
    // 调用obj.username 会运行这个函数
  },
  set() {
    // 给obj.username赋值会运行这个函数
  },
});

其中配置对象参数有多个可选值:

writable: 是否可以重写该属性

value: 当前值

get: 读取该值时会运行的函数

set: 给该值赋值时会运行的函数

enumerable: 是否可被迭代

configurable: 是否可以再次修改配置项

2.响应式原理

    Object.defineProperty方法的配置对象里面有一个函数get,每次我们访问某个变量时就会通过get函数来获得。set函数在我们给某个变量赋值时也会触发这个函数。基于这套逻辑,我们就可以想到在get方法里去保存访问过这个变量的方法,在set方法里去触发访问这个变量的方法实现数据的更新,思路有了,接下来就是实现。

3.响应式原理的实现

    假设页面上只有一个p元素,代码如下:

const pEl = document.querySelector("p");

const data = {
  username: "zr",
};
pEl.innerHTML = data.username;

    页面显示:



    接下来我们基于上面的逻辑改造一下代码。

// 创建响应式数据对象
function observer(targetObj, key) {
// 保存值,不然get方法会无限递归
const val = targetObj[key];
Object.defineProperty(targetObj, key, {
get() {
return val;
},
set(newVal) {
val = newVal;
},
});
}

const data = {
  username: "zr",
};

observer(data, "username");

function setUserNameVal() {
  pEl.innerHTML = data.username;
}
setUserNameVal();

现在基本的逻辑框架已经出来了,现在的问题是我们无法知道当前是哪个方法在访问变量。解决办法就是创建一个全局变量,通过一个函数来控制这个变量,这个变量就是当前调用变量的方法。再在get方法里面保存这个方法到数组,在set方法里触发这个数组里所有的函数。下面是代码:

let currentFn = null;

// 更新数据函数
function update(fn) {
  // 把当前运行的函数保存到全局变量中
  currentFn = fn;
  fn();
  // 收集完依赖后清空
  currentFn = null;
}
// 创建响应式数据对象
function observer(targetObj, key) {
  // 保存值,不然get方法会无限递归
  let val = targetObj[key];
  const fnList = new Set();
  Object.defineProperty(targetObj, key, {
    get() {
      // 如果是update函数访问则添加到依赖列表中,否则就是更新数据所触发的。
      currentFn && fnList.add(currentFn);
      return val;
    },
    set(newVal) {
      val = newVal;
      // 运行所有依赖该数据的函数 更新数据
      fnList.forEach((fn) => {
        fn();
      });
    },
  });
}

const data = {
  username: "zr",
};

observer(data, "username");

function setUserNameVal() {
  pEl.innerHTML = data.username;
}
update(setUserNameVal);

4.结语

    尤大大还得是尤大大,光一个响应式就蕴含了这么多开发技巧和思想在里面,更别说整个响应式系统和别的功能了,尤大大牛逼!

相关文章
|
6月前
|
JavaScript
Vue2的响应式原理
Vue2的响应式原理主要是通**过Object.defineProperty()方法来实现数据的劫持**,并结合**发布订阅者模式**进行工作。
|
6月前
|
JavaScript API
Vue3的响应式原理
Vue 3 中的响应式原理是通过使用 ES6 的 `Proxy 对象`来实现的**。在 Vue 3 中,每个组件都有一个响应式代理对象,当组件中的数据发生变化时,代理对象会立即响应并更新视图。
|
JavaScript 索引
Vue3 响应式原理(二)
Vue3 响应式原理(二)
238 0
|
3天前
|
JavaScript 前端开发 API
介绍一下Vue中的响应式原理
介绍一下Vue中的响应式原理
8 1
|
3月前
|
JavaScript 前端开发 开发者
vue2的数据响应式原理
【8月更文挑战第4天】vue2的数据响应式原理
83 0
|
6月前
|
缓存 JavaScript 前端开发
Vue 2的响应式原理是什么?
【5月更文挑战第30天】Vue 2的响应式原理是什么?
51 4
|
6月前
|
JavaScript 前端开发 开发者
Vue是如何实现响应式系统的
【4月更文挑战第16天】Vue.js 的响应式系统基于 `Object.defineProperty` 监听数据变化,通过依赖收集和setter触发更新。当数据变化时,Watcher对象通知组件异步更新视图,优化性能。对数组的特殊处理确保视图同步。这套机制让开发者专注于业务逻辑,保证了性能和稳定性。
46 0
|
6月前
|
存储 JavaScript
Vue的响应式原理是什么?
Vue的响应式原理是什么?
28 3
|
JavaScript
Vue响应式数据的原理
Vue响应式数据的原理
|
JavaScript 前端开发 Java
vue3.0 响应式原理(超详细)
彻底弄清楚 Vue 响应式原理
下一篇
无影云桌面