在大项目中,Vuex的结构如何搭建?

当我们在开发大项目时,假设在Vuex中还是没有使用modules,那么我们的state、mutations、actions将会变得十分凌乱和杂乱无章,那么下面我们使用modules,不仅要使代码简洁,还要使得结构更清晰。

我之前写了一篇关于Vuex的基础用法,初学者可以参考,Vuex基础。基础用法只能用于学习新知识,当有了基础之后,我们就需要重构代码。

Vuex结构:

在这里插入图片描述
我在store目录下创建了modules、getters.js、index.js文件,而modules中又创建了三个模块。

下面分别在三个模块中写入简单代码:

app.js:

const state = {
    
    
  count: 5,
  device: 'desktop',
}
const mutations = {
    
    
  SET_COUNT: (state, count) => {
    
    
    state.count = count
  },
}

const actions = {
    
    
  setCount({
    
     commit }, count) {
    
    
    commit('SET_COUNT', count)
  },
}

export default {
    
    
  namespaced: true,
  state,
  mutations,
  actions,
}

permission.js:

const state = {
    
    
  roles: ['admin', 'user'],
}
const mutations = {
    
    
  getRoutes: (state) => {
    
    
    return state.roles
  },
}
export default {
    
    
  namespaced: true,
  state,
  mutations,
}

user.js:

const state = {
    
    
  token: 'fjwifjwijfshufhehsuhfuehuhuis',
  name: 'YaRong',
  introduction: '大三学生一枚',
}
const mutations = {
    
    
  SET_INTRODUCTION: (state, introduction) => {
    
    
    state.introduction = introduction
  },
  SET_TOKEN: (state, token) => {
    
    
    state.token = token
  },
}
const actions = {
    
    
  setIntroduction({
    
     commit }, introduction) {
    
    
    commit('SET_INTRODUCTION', introduction)
  },
}

export default {
    
    
  namespaced: true,
  state,
  mutations,
  actions,
}

注意:namespaced属性必须设置,设置为true表明每个module有独立的命名空间,即各模块不会相互干扰,类似Vue模块的CSS中的scoped属性。

src/store/getters.js:

const getters = {
    
    
  name: (state) => state.user.name.toUpperCase(),
  count: (state) => {
    
    
    return state.app.count + '万'
  },
  length: (state) => state.permission.roles.length,
}

export default getters

注意:留意箭头函数的内容,想要获取哪个模块的state的状态,格式为:state.模块名.变量名

下面看关键的index.js文件

src/store/index.js:

import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'

Vue.use(Vuex)

const modulesFiles = require.context('./modules', true, /\.js$/)
/**
 * reduce语法:array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
 */
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
    
    
  const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1') //获取文件名:app,permission,user
  const content = modulesFiles(modulePath) //通过路径获取每个文件的内容
  modules[moduleName] = content.default //比如app.js文件,modules.app等于export default的内容
  return modules
}, {
    
    })

const store = new Vuex.Store({
    
    
  modules,
  getters,
})

export default store

上面我使用了webpack的require.context()函数,这函数的功能是什么?这样的好处是什么呢?该函数主要用来实现自动化导入模块,在前端工程中,如果遇到从一个文件夹引入很多模块的情况,可以使用这个api,它会遍历文件夹中的指定文件,然后自动导入,使得不需要每次显式的调用import导入模块。我们这里只是使用了三个模块作为示例,假如有上百个文件的,如果不使用这种方法,那么就需要写什么import来导入,这就。。。

在main.js中导入注册:

import Vue from 'vue'
import App from './App.vue'
import store from './store'
Vue.config.productionTip = false

new Vue({
    
    
  render: (h) => h(App),
  store,
}).$mount('#app')

App.vue使用:

<template>
  <div id="app">
    <h3>{
    
    {
    
    name}}</h3>
    <button @click="setToken">修改</button>
    <button @click="setIntroduction">修改</button>
  </div>
</template>

<script>
import {
    
     mapGetters } from "vuex"
export default {
    
    
  name: "App",
  components: {
    
    },
  computed: {
    
    
    ...mapGetters(['name'])
  },
  methods: {
    
    
    setToken () {
    
    
      this.$store.commit('user/SET_TOKEN', '我是修改后的token')
    },
    setIntroduction () {
    
    
      setTimeout(() => {
    
    
        this.$store.dispatch('user/setIntroduction', '我是前端工程师')
      }, 2000)
    }
  }

};
</script>

<style>
</style>

上面展示了getters、mutations、actions是如何调用的。
注意:mutations、actions的调用的第一个参数是需要指明是哪个module的东西。
在这里插入图片描述
Vuex是可以正常使用于记录状态。

在复杂的大项目中,我们只需在划分的的module中书写Vuex,这样将结构更加清晰,有利于源码的阅读。

猜你喜欢

转载自blog.csdn.net/weixin_43334673/article/details/109704976