IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> Vuex详解(二) 进阶——Vuex的模块化使用 -> 正文阅读

[JavaScript知识库]Vuex详解(二) 进阶——Vuex的模块化使用

随着项目越来越复杂,我们可能向store中添加的状态越来越多,这不便于我们对数据的管理,同时,既然vue是模块化开发,那么我们能否将Vuex中的状态也进行模块化管理呢?

Vuex——Module

Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:

const moduleA = {
  state: () => ({ ... }),
  mutations: { ... },
  actions: { ... },
  getters: { ... }
}

const moduleB = {
  state: () => ({ ... }),
  mutations: { ... },
  actions: { ... }
}

const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})

store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态

值得注意的是,这里两份模块的state写法state: () => ({ ... }),这里通过函数来返回了一个state对象。如果我们不这样写,而是使用一个纯对象来声明模块的状态,那么这个状态对象就会通过引用被共享,导致状态动向被修改时store或模块间数据互相污染的问题。实际上,这和Vue组件内的date类似,它也是使用了一个函数。

但是,模块化store对象之后,如果将所有的内容都写在一个store.js中,就显得过于臃肿,我们难以快速定位数据,这时候,我们还可以按照模块将store分成不同的文件。

import defaultState from "./state/defaultState";
import mutationsRoot from "./mutations/mutations.root";
import actionsRoot from "./actions/actions.root";
import gettersRoot from "./getters/getters.root";

import stateModuleA from "./state/state.moduleA";
import mutationsModuleA from "./mutations/mutations.moduleA";
import gettersModuleA from "./getters/getters.moduleA";
import actionsModuleA from "./actions/actions.moduleA";

export default () => {
  return new Vuex.Store({
    state: () => defaultState(),
    mutations: mutationsRoot,
    actions: actionsRoot,
    getters: gettersRoot,
    modules:{
      a: {
        namespaced: true,
        state: stateModuleA(),
        mutations: mutationsModuleA,
        getters: gettersModuleA,
        actions: actionsModuleA
      }
    }
  })
}

所以现在的目录结构为:
在这里插入图片描述

使用模块化Vuex

以下就是store中的a模块:

    modules:{
      // a: {
      //   namespaced: true,
      //   state: () => require('./state/state.moduleA').default(),
      //   mutations: () => import('./mutations/mutations.moduleA'),
      //   getters: () => import('./getters/getters.moduleA'),
      //   actions: () => import('./actions/actions.moduleA')
      // }
      a: {
        namespaced: true,
        state: () => {
          return {
            numA: 10,
            numB: 20
          }
        },
        mutations: {
          updateNum (state, data) {
            state.numA = data.numA
            state.numB = data.numB
          }
        },
        getters: {
          sum(state, getters, rootState){
            return state.numA + state.numB
          }
        },
        actions: {
          updateNumsAsync (store, data) {
            setTimeout(() => {
              store.commit('updateNum', data.nums)
            }, data.time)
          }
        }
      }
    }

app中使用模块中的状态:

<template>
  <div>
    <div>{{numA}} {{numB}}</div>
    <div>{{sum}}</div>
  </div>
</template>
<script>
import {
  mapState,
  mapMutations,
  mapActions,
  mapGetters
} from 'vuex'
export default {
  name: 'app',
  methods:{
    ...mapMutations(["a/updateNums"]),
    ...mapActions(["a/updateNumsAsync"])
  },
  mounted() {
    console.log(this.numA)
    this['a/updateNumsAsync']({
      nums: {
        numA: 50,
        numB: 40
      },
      time: 3000
    })
  },
  computed:{
    ...mapState({
      numA: state => state.a.numA,
      numB: state => state.a.numB
    }),
    ...mapGetters({
      sum: 'a/sum'
    })
  }
}
</script>

注意:

  1. 默认情况下,模块内部的 action、mutation 和 getter 是注册在全局命名空间的——这样使得多个模块能够对同一 mutation 或 action 作出响应。如果希望你的模块具有更高的封装度和复用性,你可以通过添加 namespaced: true 的方式使其成为带命名空间的模块。当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名。也就是说,我们在a模块中定义的updateNum,sum,updateNumsAsync其实是注册在全局命名空间的,但是由于我们设置了namespaced: true,所以注册这些函数时,将其名称由函数名=>模块名称/函数名,即a/updateNum等。
  2. 在使用mapGetters,mapMutations,mapActions来简化代码风格时,我们的函数名发生了改变,所以不能直接使用updateNum,而是应该使用a/updateNum;但是,如果我们使用mapState来简化代码,a模块中的state不能通过a/状态名称(即a/numA)来获取,而是通过numA: state => state.a.numA来获得。如果不使用mapState,我们可以通过this.$store.state.a.numA来获取状态。
  3. 在使用a模块下的函数时,比如...mapGetters({sum: 'a/sum'}),其实我们也可以这样...mapGetters([ 'a/sum' ]),但是,这样写并不便于在模板中使用getter函数。如果在js中,我们可以使用this['a/sum']();来调用getter函数,但是如果我们在模板中,<div>{{a/sum}}</div>,这种写法是无法达到我们的期望的。所以,在使用store模块中的函数时,我们应当先为其设置一个别名,然后通过别名使用它。
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-03 16:03:16  更:2022-03-03 16:04:24 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 8:28:48-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码