1. 为什么使用模块
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter。
命名空间 默认情况下,模块内部的 action、mutation 和 getter 是注册在全局命名空间的——这样使得多个模块能够对同一 mutation 或 action 作出响应。
如果希望你的模块具有更高的封装度和复用性,你可以通过添加 namespaced: true 的方式使其成为带命名空间的模块。当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名。
2. 下载vuex
npm i vuex
yarn add vuex // yarn
3.修改store.js
- 在src文件夹中添加store文件夹
- store.js放入store文件夹中,重命名store.js为index.js
- 在store文件夹中添加modules文件夹,来存储我们的模块js
4. 使用vuex-persistedstate状态持久化
我们可以使用状态持久化来实现缓存状态,方便我们进行存储我们的数据。使用方法如下:
-
- 下载 vuex-persistedstate
npm i vuex-persistedstate
yarn add vuex-persistedstate // yarn
-
- 使用 vuex-persistedstate
- 可以通过storage参数来修改我们存储的位置
- modules文件中注册模块
// store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import createPersistedState from 'vuex-persistedstate'
Vue.use(Vuex)
import common from './modules/common'
export default new Vuex.Store({
modules: {
common, // 公用
},
plugins: [
createPersistedState({
storage: window.sessionStorage, // 修改存储的状态
// paths: ['common'] // 存储的指定的模块的名字(存储某个模块对象)
})
] // 状态持久化
})
5. 创建模块
- 在module文件夹下创建 comomon.js
- 在store/index.js中引入common.js,并在modules注册
- 这里做了一个简单的实例,其他的都是一样的实现方式。
// state
const state = {}
// mutations
const mutations = {}
// getters
const getters = {}
// actions
const actions = {}
export default {
namespaced: true,
state,
getters,
actions,
mutations
}
6. state
- 设置state
// state
const state = {
token:''
}
- mapState 辅助函数 获取
// state
<script>
import { mapState } from 'vuex'
export default {
computed: {
// 方式1
...mapState('common', ['token']),// 映射为 `this.$store.state.common.token`
// 方式2
token () {
return this.$store.state.common.token
}
}
}
</script>
- 使用 可以用this.token获取我们的token数据,state,getters,mutations,actions都是一样是获取方式
7. Getter
- 设置 getters
Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
Getter 接受 state 作为其第一个参数:
如果你希望使用全局 state 和 getter,rootState 和 rootGetter 会作为第三和第四参数传入 getter,
// Getter
const getters = {
getToken(state){
return state.token
}
}
- mapGetters 辅助函数 获取
// Getter
<script>
import { mapGetters } from 'vuex'
export default {
computed: {
// 方式1
...mapGetters('common', ['getToken']), // 映射为 `this.$store.getters.common.getToken`
// 方式2
getToken () {
return this.$store.getters.common.getToken
}
}
}
</script>
8. Mutation
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方。
推荐使用常量来代替Mutation事件,可以让你的代码合作者对整个 app 包含的 mutation 一目了然
参数:接受 state 作为第一个参数, data第二个参数是我们需要设置的数据,这个参数的名是可以根据我们的需求设置
- Mutation
// Mutation
//设置常量
const SET_TOKEN_DATA = 'setTokenData'
const mutations = {
[SET_TOKEN_DATA](state,data){
state.token = data;
}
}
- mapMutation 辅助函数 获取
// Mutation
<script>
import { mapMutations } from 'vuex'
export default {
methods:{
// 方式1
...mapMutations('common',[
'setTokenData' // 将 `this.setTokenData()` 映射为 `this.$store.commit('common/setTokenData')`
]),
// 方式2 可以用设置别名的方式
...mapMutations({
setToken: 'common/setTokenData'
// 将 `this.setToken('123')` 映射为`this.$store.commit('common/setTokenData','123')`
}),
// 方式3 直接调用 this.$store.commit('common/setTokenData','123')
}
}
</script>
9. Action
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作。
Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters。
// Action
const Action = {
// 参数params:传入的参数(参数名可以根据需求设置)
// 方式1
getTokenData(context,params){
context.commit(SET_TOKEN_DATA, params)
},
// 方式2 参数解构的方式
getTokenData({ commit },params){
commit(SET_TOKEN_DATA, params)
},
}
- mapMutation 辅助函数 获取
// state
<script>
import { mapActions } from 'vuex'
export default {
methods:{
// 方式1
...mapActions('common',[
'getTokenData' // 将 `this.getTokenData()` 映射为 `this.$store.dispatch('common/getTokenData')`
]),
// 方式2 可以用设置别名的方式
...mapActions({
getData:'common/getTokenData'
// 将 `this.getData('123')` 映射为`this.$store.dispatch('common/getTokenData','123')`
}),
// 方式3 直接调用 this.$store.dispatch('common/getTokenData','123')
}
}
</script>
不足之处,请大家不吝指教!!!