Skip to content

Latest commit

 

History

History
166 lines (141 loc) · 4.48 KB

3.2.Vuex安装使用分析.md

File metadata and controls

166 lines (141 loc) · 4.48 KB

使用示例

我们先来看看vuex官方给的一个简单示例。

import Vue from 'vue'
import Vuex from 'vuex'
//注册vuex插件
Vue.use(Vuex)

// root state object.
// each Vuex instance is just a single state tree.
//定义state
const state = {
  count: 0
}

// mutations are operations that actually mutates the state.
// each mutation handler gets the entire state tree as the
// first argument, followed by additional payload arguments.
// mutations must be synchronous and can be recorded by plugins
// for debugging purposes.
//定义mutations
const mutations = {
  increment (state) {
    state.count++
  },
  decrement (state) {
    state.count--
  }
}

// actions are functions that cause side effects and can involve
// asynchronous operations.
//定义actions
const actions = {
  increment: ({ commit }) => commit('increment'),
  decrement: ({ commit }) => commit('decrement'),
  incrementIfOdd ({ commit, state }) {
    if ((state.count + 1) % 2 === 0) {
      commit('increment')
    }
  },
  incrementAsync ({ commit }) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        commit('increment')
        resolve()
      }, 1000)
    })
  }
}

// getters are functions
//定义getters
const getters = {
  evenOrOdd: state => state.count % 2 === 0 ? 'even' : 'odd'
}

// A Vuex instance is created by combining the state, mutations, actions,
// and getters.
//导出vuex实例
export default new Vuex.Store({
  state,
  getters,
  actions,
  mutations
})

首先注册vuex插件

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

然后分别定义state、mutations、actions、getters,并导出

最后将vuex对象实例挂载到vue的每一个实例上去

new Vue({
  el: '#root',
  router,
  store, 
  render: h => h(App)
})

vuex的安装

vuex作为vue的一个插件,在使用插件vue.use(vuex)时,会通过vuex对象中的install方法将vuex载入,现在我们来看看install方法的实现。

install方法在store.js文件中

export function install (_Vue) {
  //这里使用全局变量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)
}

这里只是用全局变量做了下判断,避免重复安装,其重点还在最后调用的applyMixin(Vue)函数上

我们来看看applyMixin函数,在mixin.js文件中

export default function (Vue) {
  const version = Number(Vue.version.split('.')[0])

  if (version >= 2) {
    //在2.x.x以上版本,直接使用hook的形式进行注入
    Vue.mixin({ beforeCreate: vuexInit })
  } else {
    // override init and inject vuex init procedure
    // for 1.x backwards compatibility.
    //在2.x.x一下版本,使用封装并替换Vue对象原型的_init方法,实现注入
    const _init = Vue.prototype._init
    Vue.prototype._init = function (options = {}) {
      options.init = options.init
        ? [vuexInit].concat(options.init)
        : vuexInit
      _init.call(this, options)
    }
  }

  /**
   * Vuex init hook, injected into each instances init hooks list.
   */
  function vuexInit () {
    const options = this.$options
    // store injection
    if (options.store) {
      //根组件就直接设置到this对象的$store属性上
      this.$store = typeof options.store === 'function'
        ? options.store()
        : options.store
    } else if (options.parent && options.parent.$store) {
      //子组件从其父组件引用$store属性,层层嵌套进行设置
      this.$store = options.parent.$store
    }
  }
}

在安装注入函数时会判断vue的版本,2.x.x以上版本,使用 hook 的形式进行注入,而低于2.x.时使用封装并替换Vue对象原型的_init方法,实现注入。

注入的函数实现的功能其实就是当vuex设置到vue对象的$store属性上,便于在任意组件中执行 this.$store 都能找到装载的那个store对象。 这里它会判断设置的是根组件还是非根组件,根组件时直接设置到this对象的$store属性上,子组件则从其父组件引用$store属性,层层嵌套进行设置。

到此,vuex的安装工作就已经完成了。

小结

这一节我们只是简单的看了一下vuex的使用方式,顺便解析了下vuex安装注入到vue实例上的过程。下节我们将进入vuex的核心内容。