Skip to content

vuex 源码:初探 vuex 之 install #2

@cobish

Description

@cobish

前言

vuex 是 vue 的一个插件,需要安装之后,才能在 vue 的基础上使用 vuex。所谓的安装,就是通过全局方法 Vue.use() 使用插件。

先来看看下面一段使用 vuex 的代码:

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

Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    count: 0
  }
})

new Vue({
  el: '#app',
  store,
  // ...
})

从这段代码中,我们可以看出初始化了一个 store 对象,将其挂载在 vue 实例上,然后就可以在各组件里使用 this.$store 来管理状态。接下来,我们就从 vuex 的源码入手,来探索 vuex 是如何被安装的。

注:本次阅读的是 vuex 的 2.0.0 版本,源码请戳 这里

解读

下载并打开项目,不知从何下手。那就先打开 package.json 吧,看到 script 的 build 命令里,都是去找 bulid 这个目录下的文件,还有不知道的 rollup 命令字样。于是打开 build 目录,看到了 rollup.config.js 并打开它。很幸运,找到了 entry 是 src/index.js。大胆猜测,rollup 是一个打包工具,入口文件是 entry,所以源码应该是在 src 目录下。

前面都只是热身动作,找到了源码,接下来就是真正地阅读源码了。

index.js

进入 src 目录,打开 index.js,发现有 300 多行代码,是准备开始逐行啃下来?别傻了,把所有的 function 先折叠起来,然后看到最下面的代码:

export default {
  Store,
  install,
  mapState,
  mapMutations,
  mapGetters,
  mapActions
}

当当当当,这里就是 vuex 暴露出来的 API,一点也不多是吧。我们只需先关注 install 这个 API。Vue.js 的插件应当有一个公开方法 install。对,就是 343 行的这个 install 方法:

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

install

这个 install 好像没做什么事情,最主要就是调用了 applyMixin 方法。于是找到了 mixin.js 文件,里面便是这个方法的实现。

我们需要关注的是 vue 2.0 版本的代码,所以直接忽视 1.0 的版本,然后生命周期则是使用 beforeCreate。经过一系列的判断,最后可以把代码简化成这样:

export default function(vue) {
  Vue.mixin({ beforeCreate: vuexInit })
  
  /**
   * Vuex init hook, injected into each instances init hooks list.
   */

  function vuexInit () {
    const options = this.$options
    // store injection
    if (options.store) {
      this.$store = options.store
    } else if (options.parent && options.parent.$store) {
      this.$store = options.parent.$store
    }
  }
}

代码实现了全局注册混合对象。从 vuexInit 这个方法得知,实际做的事情就是组件取得 vue 对象的 $options,把 $options 里的 store 赋值给 $store。当然如果 $options 没有 store,则向其 parent 向上查找并赋值。

因此,我们可以在各个组件里使用到 this.$store 来进行状态的管理,实际上就是我们初始化的 store 对象。

总结

本篇从 vuex 的安装代码 Vue.use(Vuex) 出发,然后找到 vuex 实现的 install 方法,到最后得知 vuex 实现了全局注册混合对象 applyMixin,即给每个 vue 组件都添加了 $store 属性。而 store 则是从实例化 vue 根对象时传进去,所以接下来,我们要研究的就是这个 store 对象。

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions