vue相关原理图解

vue工作原理

  1. 每一个 Vue Component(vue组件) 都有一个与之对应的 Watcher 实例。
  2. Vue 的 data 上的属性会被遍历,并用 Object.defineProperty添加 getter 和 setter 属性。
  3. 当 Vue Component 的render 函数被执行的时候, data 上会被读取, getter 方法会被调用, 此时 Vue 会去记录此 Vue component 所依赖的所有 data上的属性。(这一过程被称为依赖收集)
  4. data上的属性被改动时(主要是用户操作), 即被写入时, setter 方法会被调用,会通知watcher重新计算,watcher去通知所有依赖于此 data 的组件去调用他们的 render 函数进行更新。

Vue 对象渲染成 html DOM的过程

image.png
  1. 在 init 阶段(defineReactive), Vue 对象属性 data 的属性会被 reactive 化,即会被设置 getter 和 setter 函数
  function defineReactive(obj: Object, key: string, ...) {
    const dep = new Dep()
    Object.defineProperty(obj, key, {
      enumerable: true,
      configurable: true,
      get: function reactiveGetter () {
        ....
        dep.depend()
        return value
        ....
      },
      set: function reactiveSetter (newVal) {
        ...
        val = newVal
        dep.notify()
        ...
      }
    })
  }

Vue 在对 data 上的任何一个属性进行 reactive 化的时候,都会调用 defineReactive 函数,也就是说,对于所有被 Vue reactive 化的属性来说都有一个 Dep 对象与之对应(一个data属性对应一个Dep对象)。

  1. Vue 对象 init 后会进入 mount 阶段,这个阶段的关键一个函数就是 mountComponent:
mountComponent(vm: Component, el: ?Element, ...) {
    vm.$el = el
    ...
    updateComponent = () => {
      vm._update(vm._render(), ...)
    }
    new Watcher(vm, updateComponent, ...)
    ...
  }

对于每个 Vue 组件实例来说,只会经历一次 mount,所以都有一个 Watcher 与之对应(一个组件对应一个watcher)
vm._render 的作用,把 Vue 对象渲染成虚拟 Dom 的过程。
vm._update 方法,虚拟 Dom 去创建或更新真实 Dom 的过程。

  1. 在 Watcher 构造函数里,不仅仅创建了 Watcher 的实例,还调用了 vue 组件的更新函数updateComponent。这会导致组件的渲染函数 vm._render 被调用,触发依赖收集的逻辑
  2. 触发setter函数,直接调用 dep 的 notify, ,就是依次去调用所有依赖这个属性的所有的 Vue 组件的更新函数。

MVVM双向绑定原理

Vue.js 是采用数据劫持结合发布者-订阅者模式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。主要分为以下几个步骤:

  1. 需要observe的数据对象进行递归遍历,都加上setter和getter,当给这个对象的某个值赋值,就会触发setter,那么就能监听到了数据变化
  2. compile解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图
  3. Watcher订阅者是Observer和Compile之间通信的桥梁,主要做的事情是:
    ①在自身实例化时往属性订阅器(dep)里面添加自己
    ②自身必须有一个update()方法
    ③待属性变动dep.notify()通知时,能调用自身的update()方法,并触发Compile中绑定的回调。
  4. MVVM作为数据绑定的入口,整合Observer、Compile和Watcher三者,通过Observer来监听自己的model数据变化,通过Compile来解析编译模板指令,最终利用Watcher搭起Observer和Compile之间的通信桥梁,达到数据变化 -> 视图更新;视图交互变化(input) -> 数据model变更的双向绑定效果。
image.png

MVVM

  • Model代表数据模型,数据和业务逻辑都在Model层中定义;
  • View代表UI视图,负责数据的展示;
  • ViewModel负责监听Model中数据的改变并且控制View视图的更新,处理用户交互操作;
image.png

MVC

  • MVC 通过分离 Model、View 和 Controller 的方式来组织代码结构
  • View 负责页面的显示逻辑
  • Model 负责存储页面的业务数据以及对相应数据的操作
  • View 和 Model 应用了观察者模式, Model 层发生改变的时候它会通知有关 View 层更新页面
  • Controller 层负责用户与应用的响应操作,当用户与页面产生交互的时候,Controller 中的事件触发器就开始工作了,通过调用 Model 层,来完成对 Model 的修改,然后 Model 层再去通知 View 层更新
image.png

vue初始化及更新

  1. new Vue()首先执行初始化,对data执行响应化处理,这个过程发生Observe中
  2. 同时对模板执行编译,找到其中动态绑定的数据,从data中获取并初始化视图,这个过程发生在Compile中
  3. 同时定义⼀个更新函数和Watcher,将来对应数据变化时Watcher会调用更新函数
  4. 由于data的某个key在⼀个视图中可能出现多次,所以每个key都需要⼀个管家Dep来管理多个Watcher
  5. 将来data中数据⼀旦发生变化,会首先找到对应的Dep,通知所有Watcher执行更新函数
image.png

依赖收集

视图中会用到data中某key,这称为依赖。同⼀个key可能出现多次,每次都需要收集出来用⼀个Watcher来维护它们,此过程称为依赖收集
多个Watcher需要⼀个Dep来管理,需要更新时由Dep统⼀通知


image.png

vue 原理

  • MVVM的本质是通过数据绑定链接View和Model,让数据的变化自动映射为视图的更新。将controller中的与视图相关的逻辑放在vm层完成。
  • Vue.js采用的则是基于依赖收集的观测机制。
    • 将原生的数据改造成 “可观察对象”。一个可观察对象可以被取值,也可以被赋值。
    • 在watcher的求值过程中,每一个被取值的可观察对象都会将当前的watcher注册为自己的一个订阅者,并成为当前watcher的一个依赖。
    • 当一个被依赖的可观察对象被赋值时,它会通知所有订阅自己的watcher重新求值,并触发相应的更新。
    • Vue.js利用了ES5的Object.defineProperty方法,直接将原生数据对象的属性改造为getter和setter,在这两个函数内部实现依赖的收集和触发
    • 异步批量DOM更新:当大量数据变动时,所有受到影响的watcher会被推送到一个队列中,并且每个watcher只会推进队列一次。这个队列会在进程的下一个 “tick” 异步执行。这个机制可以避免同一个数据多次变动产生的多余DOM操作,也可以保证所有的DOM写操作在一起执行,避免DOM读写切换可能导致的layout。
      链接地址:https://www.csdn.net/article/2015-08-11/2825439-vue

vuex

  • state,驱动应用的数据源;
  • view,以声明方式将 state 映射到视图;
  • actions,响应在 view 上的用户输入导致的状态变化。

Vuex 背后的基本思想

  • 通过定义和隔离状态管理中的各种概念并通过强制规则维持视图和状态间的独立性,我们的代码将会变得更结构化且易维护。

你可能感兴趣的:(vue相关原理图解)