一、相关概念
1.store
每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。
Vuex 和单纯的全局对象有以下两点不同:
(1) Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
(2) 你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。
2.state
单一状态树:即用一个对象包含全部的应用层级状态,因此它将作为“唯一的数据源”而存在
也可以这么理解:state是store里的一个对象,里面存放的是要全局共享的数据
3.getters
vuex里的“计算属性”,getter的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
假设state存储了A和B两个变量,要实现这样一个逻辑,B恒等于A减一,那么每次当A改变时,再重新获取B明显不现实,这时候就有必要用到getter
4.mutations
更改state的唯一方法是提交(commit)mutation,mutations是一个对象,里面存放了修改state中数据的函数,这些函数接收state作为第一个参数,也可以传入额外的参数
注意:mutation必须是同步函数
提交:store.commit("increment")
5.actions
action类似于mutation,不同在于:
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作。
分发:store.dispatch("increment")
6.modules
Vuex允许将store分割成模块,每个模块拥有自己的state、mutation、action、getter
命名空间:namespaced
二、store模式(简单)
// store / index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
count: 0, // this.$store.state.count
user: ""
},
getters: {
getCount(state) {
return state.count
}
},
mutations: {
// this.$store.commit('increment')
increment(state, n) {
state.count++
},
setUser(state, name) {
state.user = name
}
},
actions: {
getUser(context) {
context.commit("Mark")
},
// this.$store.dispatch("getUser")
/* 使用ES6:
getUser({ commit }) {
commit("setUser", "Mark")
}
*/
}
})
// main.js
import store from "./store"
new Vue({
router,
store,
render: h => h(App)
}).$mount("#app");
三、模块化
1.根据业务划分模块
// store / index.js
import Vue from 'vue'
import Vuex from 'vuex'
import moduleA from './modules/moduleA'
import moduleB from './modules/moduleB'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
moduleA,
moduleB
}
})
// store / modules / moduleA.js
export default {
namespaced: true,
state: {...},
getters: {...},
mutations: {...},
actions: {...}
}
// vue组件中使用
import { mapState, mapGetters, mapActions } from 'vuex'
computed: {
...mapState({
count: state => state.moduleA.count
}),
...mapGetters("moduleA", {
count: 'getCount'
})
},
methods: {
getUserInfo() {
this.$store.dispatch('moduleA/getUser')
}
/*
...mapActions('moduleA', ['getUser'])
....mapActions({
myFunction: 'moduleA/getUser'
})
...mapMutations('moduleA', ['increment'])
*/
}
2.根据功能划分模块
// store / index.js
import Vue from 'vue'
import Vuex from 'vuex'
import actions from './actions'
import mutations from './mutations'
import state from './state'
import getters from './getters'
Vue.use(Vuex)
const store = new Vuex.Store({
actions,
mutations,
getters,
state
})
export default store
// state.js
const state = {
user: ''
}
export default state
// getters.js
import state from './state'
export default {
getUser: () => state.user
}
// mutations.js
import state from './state'
export default {
setUser: (data) => {
state.user = data
}
}
// actions.js
export default {
getUserInfo({ commit }, data) {
commit('setUser', data)
}
}