vuejs系列四-双向绑定的实现

简介: 作为一名软件开发人员,了解常用的设计模式应该算是我们必备的技能之一了。如果你在编程中可以得心应手的使用这些,那你的代码肯定是满足了健壮性,可读性,易维护的范畴之内的。本章我们一起来了解下前端开发中常用的设计模式发布 订阅。

前言


作为一名软件开发人员,了解常用的设计模式应该算是我们必备的技能之一了。如果你在编程中可以得心应手的使用这些,那你的代码肯定是满足了健壮性,可读性,易维护的范畴之内的。本章我们一起来了解下前端开发中常用的设计模式发布 订阅。

发布订阅者模式是什么

说道发布订阅者模式,那不得不提的就是观察者模式,让我们先来对比下他们基础特性(摘自维基百科):

  • 观察者模式:在此种模式中,一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实时事件处理系统。
  • 发布订阅者模式:在软件架构中,发布-订阅是一种消息范式,消息的发送者(称为发布者)不会将消息直接发送给特定的接收者(称为订阅者)。

从他们对比的特征中不难发现这两者有很多相似点:都是一对多的关系,(一个观察者对象对应多个观察者、一个发布对应多个订阅者。)都能实现数据的绑定。他们本质上的区别是发布订阅会引入Event Channel(订阅器) 来将发布的信息分发到订阅者 (所以发布订阅可以异 步处理订阅的内容)。

发布订阅者-vue中的双向绑定

DOM  ======>  数据 或 数据 ======>  DOM *从图中我们可以清楚的了解到 vue初始化时候会加载observer类,这个类是为了 实现数据劫持,通过Object.propertyDefine为其添加set和get属性,并且将这些值添加到订阅器中(deb)。

//实现observer数据劫持
export class Observer { 
    ...
    //遍历所有属性
    walk (obj: Object) {
      const keys = Object.keys(obj)
      for (let i = 0; i < keys.length; i++) {
        defineReactive(obj, keys[i])
      }
  }
}
//给属性加上get set
export function defineReactive (
  ...
) {
   Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get: function reactiveGetter () {
      ...
      if (Dep.target) {
        dep.depend()
        if (childOb) {
          childOb.dep.depend()
          if (Array.isArray(value)) {
            dependArray(value)
          }
        }
      }
      return value
    },
    set: function reactiveSetter (newVal) {
      ...
      dep.notify()
    }
  })
}
//实现订阅者
  • 我们再来看看订阅器中如何实现的,我们订阅器中需要的主要功能收集和发布。 收集observer中劫持到到数据关联对应的数据和订阅者,通知对应的订阅者订阅到数据改变。
//实现订阅器
export default class Dep {
   //收集
   addSub (sub: Watcher) {
    ...
  }
  //
  depend () {
    if (Dep.target) {
      Dep.target.addDep(this)
    }
  }
  //通知
  notify () {
      ...
  }
}

*最后我们来了解下订阅者(watcher)接受到订阅器到通知后所做到事情

export default class Watcher {
  // ...
  /**
   * Subscriber interface.
   * Will be called when a dependency changes.
   */
   // 还记得Dep.notify 调用到update
  update () {
    /* istanbul ignore else */
    if (this.lazy) {
      this.dirty = true
    } else if (this.sync) {
      this.run()
    } else {
      queueWatcher(this)
    }
  }
  /**
   * Scheduler job interface.
   * Will be called by the scheduler.
   */
   //这个方法并不是实例化Watcher的时候执行的,而是监听的变量变化的时候才执行的
  run () {
     ...
    }
  }
}

发布订阅的优缺点以及疑问

  • 优点:发布者和订阅者是解耦的,符合了软件设计高内聚,低耦合,只要引入订阅发布模式的事件中心,无论在何处都可以发布订阅。同时订阅发布者相互之间不影响。
  • 缺点:1.使用不当就会造成数据流混乱,导致代码不好维护。2.订阅发布模式需要维护事件列队,订阅的事件越多,内存消耗越大
  • 在vue中数据改变如何通知视图变化的?
    解析指令 ===> 数据劫持  ===> 触发更新(通过watcher中的set)
  • 在vue到双向绑定中订阅器如何分发数据到对应到订阅者?

总结


前期也写过总结vue源码的相关文章,那我为何此时还要再写一篇此类文章?因为随着深入对vue的使用,渐渐发现掌握vue双向绑定的设计结构是如此重要,vue的此种设计不仅可以应用于软件开发中的多种场景,而且是我们熟练掌握vue这个开发框架的必经之路。


相关文章
|
8月前
|
JavaScript 前端开发 算法
什么是Vue.js的响应式系统(reactivity system)?如何实现数据的双向绑定?
什么是Vue.js的响应式系统(reactivity system)?如何实现数据的双向绑定?
71 2
|
2月前
|
JavaScript 数据管理 Java
在 Vue 3 中使用 Proxy 实现数据双向绑定的性能如何?
【10月更文挑战第23天】Vue 3中使用Proxy实现数据双向绑定在多个方面都带来了性能的提升,从更高效的响应式追踪、更好的初始化性能、对数组操作的优化到更优的内存管理等,使得Vue 3在处理复杂的应用场景和大量数据时能够更加高效和稳定地运行。
64 1
|
2月前
|
JavaScript 开发者
在 Vue 3 中使用 Proxy 实现数据的双向绑定
【10月更文挑战第23天】Vue 3利用 `Proxy` 实现了数据的双向绑定,无论是使用内置的指令如 `v-model`,还是通过自定义事件或自定义指令,都能够方便地实现数据与视图之间的双向交互,满足不同场景下的开发需求。
65 1
|
3月前
|
JavaScript 前端开发
VUE学习三:双向绑定指令(v-mode)、组件化开发(全局组件/局部组卷/组件通信)、组件化高级(slot插槽使用)
这篇文章是关于Vue.js框架中的v-model指令和组件化开发的详细教程,涵盖了从基础使用到高级功能的多个方面。
37 1
|
3月前
|
API
vue3中父子组件的双向绑定defineModel详细使用方法
vue3中父子组件的双向绑定defineModel详细使用方法
544 0
|
6月前
|
JavaScript
vue 【详解】父子组件传值、父子组件数据双向绑定 —— : | update: |.sync | v-bind.sync | v-model(含model选项和自定义v-model)
vue 【详解】父子组件传值、父子组件数据双向绑定 —— : | update: |.sync | v-bind.sync | v-model(含model选项和自定义v-model)
64 1
|
7月前
|
JavaScript
Vue.js中实现自定义组件的双向绑定
Vue.js中实现自定义组件的双向绑定
|
7月前
|
JavaScript
vue数据的双向绑定
vue数据的双向绑定
|
7月前
|
JavaScript
Vue的双向绑定v-model详细介绍
Vue的双向绑定v-model详细介绍
|
7月前
|
JavaScript

热门文章

最新文章