使用示例

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
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插件

```vuejs
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

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

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

1
2
3
4
5
6
new Vue({
el: '#root',
router,
store,
render: h => h(App)
})

vuex的安装

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

install方法在store.js文件中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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文件中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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属性上,便于在任意组件中执行 this.store 都能找到装载的那个store对象。
这里它会判断设置的是根组件还是非根组件,根组件时直接设置到this对象的storestore属性上,子组件则从其父组件引用store属性,层层嵌套进行设置。

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

小结

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