在 Vue.js 中,观察者模式和发布订阅模式都被使用到,但它们在框架内部实现中有所不同。

Vue 2 中的模式

Vue 2 主要使用了观察者模式

在 Vue 2 中,数据变化是通过观察者模式来实现响应式的。

观察者模式在 Vue 2 中的实现
  1. 数据对象的响应式处理

    • Vue 2 使用 Object.defineProperty 来实现数据对象的响应式。每个数据属性都被包装成一个 Dep 对象,这个对象用于收集依赖(观察者)。
  2. 依赖收集

    • 当组件在渲染过程中访问某个响应式属性时,该属性的 getter 被调用,当前的渲染函数(Watcher)被添加到 Dep 的依赖列表中。
  3. 通知更新

    • 当响应式数据变化时,setter 被调用,Dep 会通知所有依赖(Watcher)进行更新,触发重新渲染。

      观察者模式(Observer Pattern)

      定义

      观察者模式是一种行为设计模式,它定义了对象间的一对多依赖关系。当一个对象的状态发生变化时,所有依赖于它的对象都会得到通知并自动更新。

      结构
    • Subject(主体/被观察者):状态发生变化时,通知所有观察者。
    • Observer(观察者):定义一个更新接口,用于接收通知。
    • ConcreteSubject(具体主体):实现具体的状态和通知逻辑。
    • ConcreteObserver(具体观察者):实现具体的更新逻辑。
    • 示例代码
      class Subject {
        constructor() {
          this.observers = [];
        }
      
        addObserver(observer) {
          this.observers.push(observer);
        }
      
        removeObserver(observer) {
          this.observers = this.observers.filter(obs => obs !== observer);
        }
      
        notifyObservers() {
          this.observers.forEach(observer => observer.update());
        }
      }
      
      class Observer {
        update() {
          // 更新逻辑
        }
      }
      
      // 示例使用
      const subject = new Subject();
      const observer1 = new Observer();
      const observer2 = new Observer();
      
      subject.addObserver(observer1);
      subject.addObserver(observer2);
      
      subject.notifyObservers();  // 所有观察者接收到通知并更新
      
Vue 3 中的模式

Vue 3 引入了 Proxy 并结合使用观察者模式和发布订阅模式,实现了更高效和灵活的响应式系统。

观察者模式和 Proxy

希望这些解释能够帮助你理解 Vue 2 和 Vue 3 在实现响应式系统时使用的不同设计模式。

  1. 数据对象的响应式处理

    • Vue 3 使用 ES6 的 Proxy 来实现数据对象的响应式,取代了 Object.definePropertyProxy 可以直接拦截对对象的操作,更加灵活和高效。
  2. 依赖收集和通知更新

    • Vue 3 中的依赖收集和通知更新机制依然使用观察者模式。当响应式数据的某个属性被读取时,依赖收集器会记录当前的副作用函数(effect)。当数据变化时,依赖收集器会通知所有相关的副作用函数重新执行。
      const handler = {
        get(target, key, receiver) {
          track(target, key);
          return Reflect.get(target, key, receiver);
        },
        set(target, key, value, receiver) {
          const result = Reflect.set(target, key, value, receiver);
          trigger(target, key);
          return result;
        }
      };
      
      function reactive(target) {
        return new Proxy(target, handler);
      }
      
      发布订阅模式
    • 组合式 API 和副作用管理
  3. Vue 3 的组合式 API 允许开发者更灵活地组织代码,通过 setup 函数中的 watchwatchEffect 等方法实现对响应式数据的订阅。这里的 watch 和 watchEffect 实际上是发布订阅模式的一种应用,数据变化时触发相应的回调函数。
    import { reactive, watchEffect } from 'vue';
    
    const state = reactive({ count: 0 });
    
    watchEffect(() => {
      console.log(`count is: ${state.count}`);
    });
    
    // 修改 state.count 会触发 watchEffect 中的回调
    state.count++;
    

    总结

  4. Vue 2 主要使用 观察者模式 实现响应式系统,通过 Object.defineProperty 实现数据属性的拦截和依赖收集。
  5. Vue 3 使用 Proxy 结合 观察者模式和发布订阅模式,实现更高效和灵活的响应式系统,同时通过组合式 API 提供更强大的响应式数据处理能力。
GitHub 加速计划 / vu / vue
207.55 K
33.66 K
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:3 个月前 )
73486cb5 * chore: fix link broken Signed-off-by: snoppy <michaleli@foxmail.com> * Update packages/template-compiler/README.md [skip ci] --------- Signed-off-by: snoppy <michaleli@foxmail.com> Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 5 个月前
e428d891 Updated Browser Compatibility reference. The previous currently returns HTTP 404. 6 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐