vuex模块化(module)

10,266 阅读3分钟

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状态持久化

我们可以使用状态持久化来实现缓存状态,方便我们进行存储我们的数据。使用方法如下:

    1. 下载 vuex-persistedstate
npm i vuex-persistedstate
yarn add vuex-persistedstate // yarn 
    1. 使用 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>

不足之处,请大家不吝指教!!!