Vue 2当中使用了哪些设计模式(一)

377 阅读4分钟

1. 观察者模式(Observer Pattern)

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

观察者模式是 Vue 2 最为核心的设计模式之一,尤其在其响应式数据系统中占据了举足轻重的地位。在 Vue 2 中,观察者模式通过数据劫持机制(Object.defineProperty)和依赖追踪机制,建立了一个“发布-订阅”的模型,确保视图与数据之间的双向绑定。它的核心是,当数据变化时,能够自动通知依赖这个数据的组件更新视图。

1.1 观察者模式的工作原理

Vue 2 中的响应式系统通过数据劫持机制实现了观察者模式的核心部分。具体而言,当我们定义 data 对象时,Vue 会通过 Object.defineProperty 将每个属性的 getter 和 setter 方法进行代理,从而使得数据变得“可观察”。每当数据变化时,setter 会被触发,触发对应的依赖更新。

1.1.1 数据劫持和依赖收集

// Vue 会把 data 中的每个属性都变成 getter 和 setter
Object.defineProperty(obj, 'message', {
  get: function () {
    // 当读取 message 时,这里会被调用,进行依赖收集
    return this._message;
  },
  set: function (newValue) {
    // 当修改 message 时,这里会被调用,触发视图更新
    this._message = newValue;
    // 通知所有依赖该属性的视图更新
  }
});

在 Vue 2 中,每个数据对象都有一个“观察者”,它会监听数据的变化,并通知所有依赖该数据的组件进行视图更新。具体的实现过程是:

  1. 数据劫持:Vue 使用 Object.defineProperty 对每个数据属性进行代理,将其转换为 getter 和 setter,从而能够跟踪每个属性的访问和修改。
  2. 依赖收集:当组件访问某个数据属性时,Vue 会记录该属性与组件的关系,即视图依赖于哪些数据属性。这一过程叫做“依赖收集”。
  3. 视图更新:当数据变化时,Vue 会通过 setter 触发相应的更新操作,通知所有依赖该数据的组件重新渲染。

1.2 观察者模式在 Vue 2 中的优势

  • 自动更新视图:数据和视图之间的双向绑定,使得开发者只需关注数据的更新,视图会自动同步更新,减少了手动操作 DOM 的麻烦。
  • 简化开发流程:通过数据驱动视图更新,Vue 的响应式系统极大简化了组件开发和状态管理,减少了代码冗余和潜在的错误。 单例模式是另一种在 Vue 2 中广泛应用的设计模式,特别是在 Vue 实例、Vuex 和 Vue Router 等全局对象的管理中。单例模式确保一个类只有一个实例,并提供一个全局访问点。

2. 单例模式(Singleton Pattern)

单例模式是创建一个类,并确保该类只有一个实例。在 Vue 中,单例模式的应用体现在 Vue 实例的全局管理和插件机制上。

2.1 Vue 实例的单例模式

在 Vue 2 中,Vue 实例通常是一个单例对象。整个应用只有一个 Vue 根实例,它负责挂载整个应用并管理所有子组件。

let vm = new Vue({
  el: '#app',
  data: {
    message: 'Hello, Vue!'
  }
});

在上面的代码中,vm 就是一个全局唯一的 Vue 实例,它会负责管理 data 中的数据、生命周期钩子和视图渲染等操作。

2.2 Vuex Store 的单例模式

Vuex 是 Vue 的状态管理库,它也采用了单例模式。在一个 Vue 应用中,Vuex Store 只有一个实例。Vuex 的状态、mutations、actions 等都是通过这个单一的 Store 实例进行管理的。

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++;
    }
  }
});

通过 Vuex Store 实现应用的状态管理时,Store 实例作为单例存在,确保了整个应用的状态在多个组件之间保持一致性。

2.3 Vue Router 的单例模式

Vue Router 也是 Vue 2 中一个重要的插件,它用于管理页面的路由跳转。Vue Router 采用单例模式,保证了路由配置只有一个实例,并且该实例在整个应用中共享。

const router = new VueRouter({
  routes: [
    { path: '/', component: Home },
    { path: '/about', component: About }
  ]
});

通过这种方式,Vue Router 保证了应用中的路由配置是全局共享的,并且避免了不同组件中对路由状态的重复创建。