vue是如何收集依赖的

vue是如何收集依赖的

Vue.js 是通过其响应式系统来收集依赖的。1、数据劫持2、依赖收集3、依赖触发。Vue 使用了一个叫做 "依赖追踪" 的机制,通过监听数据的变化来自动更新视图。下面我们将详细介绍 Vue.js 是如何实现这一过程的。

一、数据劫持

Vue.js 使用 Object.defineProperty() 来劫持(或拦截)对象的属性。这使得 Vue.js 能够在属性被访问或修改时自动执行一些操作。

  • 对象劫持:Vue.js 会遍历数据对象的所有属性,并使用 Object.defineProperty() 将这些属性转换为 getter 和 setter。
  • 拦截操作:在 getter 中,Vue.js 会收集依赖;在 setter 中,Vue.js 会触发依赖。

function defineReactive(obj, key, val) {

Object.defineProperty(obj, key, {

get() {

// 依赖收集

return val;

},

set(newVal) {

if (newVal !== val) {

val = newVal;

// 依赖触发

}

}

});

}

二、依赖收集

依赖收集是 Vue 响应式系统的核心部分。当访问数据属性时,Vue 会记录哪些组件依赖于这些属性,这样当属性发生变化时,Vue 可以知道哪些组件需要重新渲染。

  • Dep 对象:每个响应式属性都有一个对应的 Dep 对象,用于存储依赖于该属性的 Watcher。
  • Watcher 对象:每个组件对应一个 Watcher 对象,用于订阅属性的变化。

class Dep {

constructor() {

this.subs = [];

}

addSub(sub) {

this.subs.push(sub);

}

notify() {

this.subs.forEach(sub => sub.update());

}

}

class Watcher {

constructor(vm, exp, cb) {

this.vm = vm;

this.exp = exp;

this.cb = cb;

this.value = this.get();

}

get() {

Dep.target = this;

let value = this.vm[this.exp];

Dep.target = null;

return value;

}

update() {

let value = this.vm[this.exp];

let oldValue = this.value;

if (value !== oldValue) {

this.value = value;

this.cb.call(this.vm, value, oldValue);

}

}

}

三、依赖触发

当数据发生变化时,Vue 会触发依赖,并通知所有订阅了该属性变化的 Watcher 执行更新操作。

  • 触发更新:在 setter 中,当数据发生变化时,会调用 Dep 的 notify 方法,通知所有的 Watcher。
  • 更新组件:Watcher 收到通知后,会执行 update 方法,重新计算新值,并调用回调函数更新视图。

function defineReactive(obj, key, val) {

const dep = new Dep();

Object.defineProperty(obj, key, {

get() {

if (Dep.target) {

dep.addSub(Dep.target);

}

return val;

},

set(newVal) {

if (newVal !== val) {

val = newVal;

dep.notify();

}

}

});

}

四、实例说明

通过一个简单的实例,我们可以更清楚地看到 Vue 是如何收集依赖并触发更新的。

let data = { message: "Hello Vue!" };

defineReactive(data, 'message', data.message);

let vm = {

message: data.message

};

new Watcher(vm, 'message', (newVal, oldVal) => {

console.log(`Message changed from ${oldVal} to ${newVal}`);

});

data.message = "Hello World!";

// 控制台输出: Message changed from Hello Vue! to Hello World!

在这个实例中,当我们修改 data.message 时,Watcher 会被通知到,并输出相应的信息。这样,我们就实现了一个简单的响应式系统。

五、总结与建议

通过以上的介绍,我们了解了 Vue.js 是如何通过数据劫持、依赖收集和依赖触发来实现响应式系统的。这一机制使得 Vue.js 能够高效地管理数据和视图之间的关系,自动更新视图,减少手动操作的繁琐和错误。

为了更好地理解和应用 Vue.js 的依赖收集机制,建议读者:

  1. 深入学习 JavaScript 中的 Object.defineProperty() 方法。
  2. 了解设计模式中的观察者模式(Observer Pattern),因为 Vue.js 的响应式系统是这一模式的具体应用。
  3. 实践编写一些简单的响应式系统,逐步加深对依赖收集和触发机制的理解。

通过不断学习和实践,相信你会对 Vue.js 的响应式系统有更深刻的理解和掌握。

相关问答FAQs:

1. 什么是依赖收集?
依赖收集是Vue框架中的一个重要概念,用于追踪数据属性与视图之间的关联关系。当数据属性发生变化时,依赖收集会自动更新相关的视图。

2. Vue是如何收集依赖的?
Vue的依赖收集是通过观察者模式实现的。在Vue的内部,每个组件都有一个Watcher实例,它负责监听组件内部数据的变化。当组件初始化时,Vue会在模板中解析指令和表达式,并创建相应的Watcher实例。Watcher实例会将自身添加到被观察的数据属性的依赖列表中。

3. 依赖收集的工作原理是什么?
当Vue组件初始化完成后,Watcher实例会开始执行依赖收集的工作。依赖收集的过程包括以下几个步骤:

  • 遍历模板中的所有指令和表达式,解析它们对应的数据属性。
  • 在解析过程中,如果发现一个数据属性被使用,Watcher实例会将自身添加到该数据属性的依赖列表中。
  • 如果该数据属性已经有其他Watcher实例监听,Watcher实例会将自身添加到该依赖列表中,如果没有,则创建一个新的依赖列表。
  • 当数据属性发生变化时,被监听的Watcher实例会被通知,它们会执行相应的更新操作,更新视图。

通过这种方式,Vue实现了对数据属性与视图之间的绑定关系的自动追踪和更新。这使得开发者可以专注于数据的变化,而不需要手动去更新视图,提高了开发效率。

文章标题:vue是如何收集依赖的,发布者:不及物动词,转载请注明出处:https://worktile.com/kb/p/3655612

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
不及物动词的头像不及物动词

发表回复

登录后才能评论
注册PingCode 在线客服
站长微信
站长微信
电话联系

400-800-1024

工作日9:30-21:00在线

分享本页
返回顶部