了解
首先,我们需要了解Vuex是什么。
Vuex 是什么?Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具 devtools extension (opens new window),提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。
Vuex有State、Getters、Mutations、Actions和Modules五个模块。
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)
Modules模块更像扩展功能,所以实际上核心概念就是State、Getters、Mutations、Actions。
State:类似Vue中的data,提供响应式数据。
Getter:类似Vue中的computer。
Mutation:更改 Vuex 的 store 中的状态的唯一方法是提交 mutation,在mutation中可以对store进行修改。
Action:类似于 mutation,不同在于:
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作。
使用
Vuex使用示例:
使用vue-cli创建的项目
// main.js
import Vue from 'vue'
import App from './App.vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
count: 0
},
getter: {
doubleCount(state){
return this.state * 2
}
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment')
}
}
})
new Vue({
render: h => h(App),
store,
}).$mount('#app')
// App.vue
<template>
<div id="app">
{{$store.state.count}}
{{$store.getters.doubleCount}}
<button @click="$store.commit('increment')">commit increment</button>
<button @click="$store.dispatch('increment')">dispatch action</button>
</div>
</template>
<script>
export default {
name: 'App',
}
</script>
运行界面大概是这个样子,点击按钮第一个数增加1,第二个数总是第一个数的2倍。
编码
我们先看实例和 vuex 有关的代码。
import Vuex from 'vuex' // 从vuex导入Vuex
Vue.use(Vuex) // 注册
const store = new Vuex.Store({ // 实例化一个Store
state
getter
mutations
actions
})
new Vue({
....
store, // 挂载
})....注册和挂载 是 Vue的插件语法,我们先不需要管。
那么首先实现 import Vuex from 'vuex' 。
在main.js同级创建 mini-vuex.js 文件,coding....
// mini-vuex.js
export default{
}
// main.js
import Vuex from './mini-vuex'此时 Vuex==={}。接着,实现
const store = new Vuex.Store({ // 实例化一个Store
state
getter
mutations
actions
})这段代码说明,Vuex里有个Store类,接收state getter mutations actions四个参数。
// mini-vuex.js
class Store { // 使用class语法糖
constructor(options = {}) {
const {
state = {},
mutations = {},
getters = {},
actions = {}
} = options
}
}
export default{
Store,
}如果想看通过原型实现的代码可以使用Babel转换成es5。
接下来,就是四大模块的核心实现了,直接使用代码+注释进行解释:
import Vue from 'vue'
class Store {
constructor(options = {}) {
const {state = {}, mutations = {}, getters = {}, actions = {}} = options
this._mutations = mutations
this._actions = actions
// 使 data 具有 响应式功能
this._vm = new Vue({
data: {
$$state: state
}
})
this._getters = getters
this.getters = null
// 将 传入的 getters 上的按照 key 绑定到 this.getters 上
Object.keys(getters).forEach(key => {
Object.defineProperty(this.getters, key, {
get: () => {
return this._getters[key](this.state)
}
})
})
}
get state(){ // 定义 变量 state 的 getter 函数
return this._vm.$data.$$state
}
commit(type, payload) {
if (this._mutations[type]) {
this._mutations[type](this.state, payload)
} else {
console.log("not found mutations")
}
}
dispatch(type, payload) {
if (this._actions[type]) {
this._actions[type].call(this, payload)
} else {
console.log("not found actions")
}
}
}
export default {Store}