欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Vuex的原理解析

程序员文章站 2022-03-04 18:41:04
...

一、Vuex的设计思想

Vuex的设计思想,借鉴了Flux、Redux,将数据存放到全局的store,再将store挂载到每个vue实例组件中,利用Vue.js的细粒度数据响应机制来进行高效的状态更新。
看了Vuex设计思想,心里难免会有这样的疑问:
1、vuex的store是如何挂载注入到组件中呢?
2、vuex的state和getters是如何映射到各个组件实例中响应式更新状态呢?

二、Vuex的原理解析

我们来看下vuex的源码,分析看看上面2个疑惑的问题:

疑问1:vuex的store是如何挂载注入到组件中呢?

1、在vue项目中先安装vuex,核心代码如下:

import Vuex from 'vuex';
Vue.use(vuex);// vue的插件机制

2、利用Vue的插件机制,使用Vue.use(vuex)时,会调用vuex的install方法,装载vuex,install方法的代码如下:

export function install (_Vue) {
  if (Vue && _Vue === Vue) {
    if (process.env.NODE_ENV !== 'production') {
      console.error(
        '[vuex] already installed. Vue.use(Vuex) should be called only once.'
      )
    }
    return
  }
  Vue = _Vue
  applyMixin(Vue)
}

  分析源码,我们知道了vuex是利用vue的mixin混入机制,在beforeCreate钩子前混入vuexInit方法,vuexInit方法实现了store注入vue组件实例,并注册了vuex store的引用属性$store。store注入过程如下图所示:

Vuex的原理解析

疑问2:vuex的state和getters是如何映射到各个组件实例中响应式更新状态呢?

store的源码在src/store.js中:

1、我们在源码中找到resetStoreVM核心方法:

function resetStoreVM (store, state, hot) {
  const oldVm = store._vm

  // 设置 getters 属性
  store.getters = {}
  const wrappedGetters = store._wrappedGetters
  const computed = {}
  // 遍历 wrappedGetters 属性
  forEachValue(wrappedGetters, (fn, key) => {
    // 给 computed 对象添加属性
    computed[key] = partial(fn, store)
    // 重写 get 方法
    // store.getters.xx 其实是访问了store._vm[xx],其中添加 computed 属性
    Object.defineProperty(store.getters, key, {
      get: () => store._vm[key],
      enumerable: true // for local getters
    })
  })

  const silent = Vue.config.silent
  Vue.config.silent = true
  // 创建Vue实例来保存state,同时让state变成响应式
  // store._vm._data.$$state = store.state
  store._vm = new Vue({
    data: {
      $$state: state
    },
    computed
  })
  Vue.config.silent = silent

  // 只能通过commit方式更改状态
  if (store.strict) {
    enableStrictMode(store)
  }
}

  从上面源码,我们可以看出Vuex的state状态是响应式,是借助vue的data是响应式,将state存入vue实例组件的data中;Vuex的getters则是借助vue的计算属性computed实现数据实时监听。

       computed计算属性监听data数据变更主要经历以下几个过程:

Vuex的原理解析

小结

  Vuex是通过全局注入store对象,来实现组件间的状态共享。在大型复杂的项目中(多级组件嵌套),需要实现一个组件更改某个数据,多个组件自动获取更改后的数据进行业务逻辑处理,这时候使用vuex比较合适。假如只是多个组件间传递数据,使用vuex未免有点大材小用,其实只用使用组件间常用的通信方法即可。

 

 

 

相关标签: vue