Vuex模块化 深入浅出超详细
Vuex 模块化
为什么需要模块化? 随着项目规模的增长,单一的 store 文件会变得庞大且难以管理;
Vuex 的模块化是一种组织和管理应用状态的策略:,它允许将全局的状态管理分解成更小、更可管理的部分;

-
逻辑清晰: 将相关的状态、getter、mutation、action 分组,使得代码结构更加清晰;
-
命名空间: 避免不同模块间命名冲突,通过模块化可以为每个模块,提供一个唯一的命名空间,方便管理;
-
性能与维护: 模块化不仅提高了代码的可读性和可维护性,还能通过合理组织逻辑,间接提升应用的性能,
尤其是在大型应用中,通过懒加载和按需导入模块,可以进一步优化资源加载;
模块化实现步骤:
创建模块文件: 在 store 目录下创建子目录,比如 modules 、在该目录下为每个模块创建单独的文件,如 modulediy.js
/** 自定义Vuex模块: 声明并对外暴漏 state、mutations、actions、getters */
const state = { userInfo: { name: 'zs', age: 18 }, }
const mutations = { }
const actions = { }
const getters = { }export default { state, mutations, actions, getters }
src/store/index.js: 文件中的modules配置项中,导入、注册这个模块;
// 导入 vue、vuex
import Vue from 'vue'
import Vuex from 'vuex'
import modulediy from './modules/modulediy' //导入用户模块Vue.use(Vuex)//创建仓库 store 状态,即数据:
const store = new Vuex.Store({//注册模块modules:{modulediy,}
})// 导出仓库 store
export default store
在组件中使用模块化状态: 创建Son4.vue组件—>组件内通过:$store.state.模块名.属性名 查看获取Vuex模块化数据;
<template><div class="box"><h2>Son4 子组件</h2>从vuex中获取的值: <label>{{ $store.state.count }}</label><hr/>从vuex modulediy 模块中获取的值: <label>{{ $store.state.modulediy.userInfo }}</label></div>
</template>

获取模块 state数据
尽管已经分模块了,但其实子模块的状态,还是会挂到根级别的 state 中,属性名就是模块名,使用模块中的数据:
-
方式一: 直接通过模块名访问:
$store.state.模块名.xxx -
方式二: 通过
mapState映射,注意:Vuex模块中需要开启命名空间namespaced : true默认根级别的映射
mapState([ '内部属性名','内部属性名','模块名' ])指定子模块的映射 :
mapState('模块名', ['模块内对应属性名xx'])
<template><div class="box"><h2>Son4 子组件</h2>从vuex中获取的值: <label>{{ $store.state.count }}</label><hr/>从vuex modulediy 模块中获取的值: <label>{{ $store.state.modulediy.userInfo }}</label><hr/>从vuex mapState中获取值: <label>{{ count }}</label><hr/>从vuex mapState中获取模块对象: <label>{{ modulediy }}</label><hr/>从vuex mapState 获取指定模块中获取的值: <label>{{ userInfo }}</label><hr/></div>
</template>
<script>import { mapState,mapGetters,mapMutations,mapActions } from 'vuex'; export default { //计算属性:computed:{...mapState(['count','modulediy']), //获取内部属性、modulediy模块对象;...mapState('modulediy',['userInfo']), //还支持直接获取指定模块内、属性对象;}}
</script>

获取模块 gatters数据
modules/modulediy.js: gatters 和 state操作类似:对于启用了命名空间的模块,支持使用 mapGetters 辅助函数时;
const state = { userInfo: { name: 'zss', age: 18 }, str:"自定义模块state属性"
}
const getters = { getstr(state){ return `年龄+1:${state.userInfo.age+1}` }
}
export default { //开启命名空间namespaced : true, state,getters
}
组件获取模块gatters数据:
- 方式一: 直接通过模块名访问
$store.getters['模块名/属性名'] - 方式二: 通过
mapGetters映射,子模块的映射mapGetters('指定模块名', ['模块内属性名'])
注意:Vuex模块中需要开启命名空间 namespaced : true
<template><div class="box"><h2>Son4 子组件</h2>从vuex中获取的值: <label>{{ $store.state.count }}</label><hr/>从vuex modulediy 模块中获取的值: <label>{{ $store.state.modulediy.userInfo }}</label><hr/>从vuex mapState中获取值: <label>{{ count }}</label><hr/>从vuex mapState中获取模块对象: <label>{{ modulediy }}</label><hr/>从vuex mapState 获取指定模块中获取的值: <label>{{ userInfo }}</label><hr/>从vuex modulediy 模块getters中直接获取 <label>{{ $store.getters['modulediy/getstr'] }}</label><hr/>从vuex modulediy 模块mapGetters中映射获取 <label>{{ getstr }}</label><hr/></div>
</template>
<script>import { mapState,mapGetters,mapMutations,mapActions } from 'vuex'; export default { //计算属性: mapState 和 mapGetters 都是映射属性computed:{...mapState(['count','modulediy']), //获取内部属性、modulediy模块对象;...mapState('modulediy',['userInfo']), //还支持直接获取指定模块内、属性对象; 需要开启命名空间;//mapGetters中映射获取 子模块的映射...mapGetters('modulediy',['getstr']), }}
</script>
获取模块 mutations数据
Vuex模块化操作:mutations, 针对所在模块,对其state 状态数据,进行修改的操作;
定义模块的 Mutations: 和正常的Vuex中定义类似,如下:定义函数给模块内修改用户对象age值;
/** 自定义Vuex模块: 声明并对外暴漏 state、mutations、actions、getters */
const state = { userInfo: { name: 'zss', age: 18 }, str:"自定义模块state属性" }
const getters = { getstr(state){ return `用户虚岁: ${state.userInfo.age+1}` } }const mutations = { //接收两个参数: state(必须 状态数据) payload(可选 传递参数)upgradeAgeM(state,payload){ state.userInfo.age+=payload }
}
const actions = { }export default { namespaced : true, //开启命名空间state,getters,mutations,actions,
}
组件内使用:Vuex组件 Mutations:
-
方式一: 原生方式直接通过
store调用:$store.commit('模块名/处理函数名', '传递参数') -
方式二: 通过
mapMutations辅助函数映射子模块:mapMutations('模块名',['处理函数名'])
推荐的方式是使用 mapMutations 辅助函数,它可以帮助你将模块的 mutations 映射到组件的方法中,需要开启命名空间
<template><div class="box"><h2>Son5 子组件</h2>从vuex中获取的值: <label>{{ $store.state.count }}</label><hr/>从vuex modulediy 模块中获取的值: <label>{{ $store.state.modulediy.userInfo }}</label><hr/>从vuex modulediy 模块getters中直接获取 <label>{{ $store.getters['modulediy/getstr'] }}</label><hr/>直接调用:<button @click="upgradeAge(1)" >给modulediy模块用户age+1</button><hr/>mapMutations调用:<button @click="upgradeAgeM(-1)" >给modulediy模块用户age-1</button><hr/></div>
</template>
<script>
import { mapState,mapGetters,mapMutations,mapActions } from 'vuex'; export default { // mapMutations 和 mapActions 都是映射方法methods: {//原生方式调用Vuex组件: 给用户添加年龄;upgradeAge(n){ this.$store.commit('modulediy/upgradeAgeM',n) },//mapMutations 子模块映射至methods 获取模块函数;...mapMutations('modulediy',['upgradeAgeM']),}}
</script>

获取模块 action数据
Vuex 组件action: 只要是针对组件的,mutations 进行异步操作扩展,本质和mutations 操作类似;
定义模块的 action: 如下:内部调用mutations 修改age函数,给其加上异步延迟的操作;
const actions = { //actions处理异步: 不能直接操作state 还需要context.commit('mutation名','传参');upgradeAgeMSync(context,num){ setTimeout(() => { context.commit('upgradeAgeM', num) }, 1000) }
}
组件内使用:Vuex组件 action:
-
方式一: 原生方式直接通过
store调用:$store.dispatch('模块名/处理函数名', '传递参数') -
方式二: 通过
mapActions辅助函数映射子模块:mapActions('模块名',['处理函数名'])
<template><div class="box"><h2>Son5 子组件</h2>从vuex中获取的值: <label>{{ $store.state.count }}</label><hr/>从vuex modulediy 模块中获取的值: <label>{{ $store.state.modulediy.userInfo }}</label><hr/>从vuex modulediy 模块getters中直接获取 <label>{{ $store.getters['modulediy/getstr'] }}</label><hr/>直接调用:<button @click="upgradeAge(1)" >给modulediy模块用户age+1</button><hr/>mapMutations调用:<button @click="upgradeAgeM(-1)" >给modulediy模块用户age-1</button><hr/><br/>直接调用:<button @click="upgradeAgeSync(1)" >延迟给modulediy模块用户age+1</button><hr/>mapActions调用:<button @click="upgradeAgeMSync(-1)" >延迟给modulediy模块用户age+1</button><hr/></div>
</template>
<script>
import { mapState,mapGetters,mapMutations,mapActions } from 'vuex'; export default { // mapMutations 和 mapActions 都是映射方法methods: {//原生方式调用Vuex mutations组件: 给用户添加年龄;upgradeAge(n){ this.$store.commit('modulediy/upgradeAgeM',n) },//mapMutations 子模块映射至methods 获取模块函数;...mapMutations('modulediy',['upgradeAgeM']),//原生方式调用Vuex actions组件: 延迟给用户添加年龄;upgradeAgeSync(n){ this.$store.dispatch('modulediy/upgradeAgeMSync',n) },//mapActions 子模块映射至methods 获取模块函数;...mapActions('modulediy',['upgradeAgeMSync']),}}
</script>

Mutations 必须是同步的原因:
mutation保证了每次同步执行之后,应用状态都会立即发生变化: 这使得时间旅行调试time-travel debugging成为可能;
DevTools 可以在每次 mutation 后捕获状态快照,从而支持状态的回溯和前进;
明确职责: mutations 专注于状态的直接变更,保持代码的纯净和单一职责原则;
状态一致性: 确保状态改变的可预测性,每个 mutation 完成后都能对应到一个明确的新状态,便于理解和测试
Actions 支持异步的原因:
actions 提供了一个封装异步操作和业务逻辑的地方:
可以触发多个mutations 来分步骤改变状态,使得代码结构更清晰,易于维护,Actions是对 Mutations的异步扩展升级;
代码管理:
本代码已经使用Git进行管理: 公众号回复:Vue项目工程化

相关文章:
Vuex模块化 深入浅出超详细
Vuex 模块化 为什么需要模块化? 随着项目规模的增长,单一的 store 文件会变得庞大且难以管理; Vuex 的模块化是一种组织和管理应用状态的策略:,它允许将全局的状态管理分解成更小、更可管理的部分; 逻辑清…...
细说MCU检测按键输入的外部中断和修改HAL_GPIO_EXTI_IRQHandler() 的实现方法
目录 一、 硬件板及设计目的 二、建立工程 1.配置GPIO 2.配置时钟源和Debug 3.配置系统时钟 4.配置NVIC 三、代码编写 四、修改HAL_GPIO_EXTI_IRQHandler() 一、 硬件板及设计目的 本文使用的硬件板是ST的开发板NUCLEO-G474RE,板上MCU型号为ST…...
昂科烧录器支持XHSC小华半导体的32位微控制器HC32F005C6P
芯片烧录行业领导者-昂科技术近日发布最新的烧录软件更新及新增支持的芯片型号列表,其中XHSC小华半导体的32位微控制器HC32F005C6P已经被昂科的通用烧录平台AP8000所支持。 HC32F005C6P是Low Pin Count、宽电压工作范围的MCU,集成12位1Msps高精度SARADC…...
根据 IP 地址配置子网示例(下挂 hub 接不同 vlan 终端)
我们一般根据端口配置子网比较简单,但是如果换接口,就又要到交换机上重新配置端口所属 vlan 了,紧急情况下,还是比较耽误时间的。但如果根据IP地址配置 vlan,则可以插在交换机上任意端口,排障时比较节省时间…...
Flink-DataWorks第四部分:数据同步(第60天)
系列文章目录 2.4.2 DataStudio侧实时同步 2.4.3 数据集成侧同步任务 文章目录 系列文章目录前言2.4.2 DataStudio侧实时同步2.4.3 数据集成侧同步任务 前言 本文主要详解了DataWorks的数据同步,为第四部分: 由于篇幅过长,分章节进行发布。…...
go post请求,参数是raw json格式,response是固定结构。
在Go语言中,使用net/http包可以很方便地发送HTTP请求,包括POST请求。当需要发送raw JSON格式的参数时,通常会使用encoding/json包来将Go的结构体序列化为JSON字符串,然后使用http.NewRequest函数创建请求,并通过http.C…...
国产开源大模型都有哪些?
随着ChatGPT引领的大模型热潮,国内的公司开始相继投入研发自己的人工智能大模型,截止到2023年10月,国产公司的大模型有近百个,包括一些通用大模型,比如百度的文心一言,也有特定领域的专用大模型,…...
基于Hadoop的超市进货推荐系统设计与实现【springboot案例项目】
文章目录 有需要本项目的代码或文档以及全部资源,或者部署调试可以私信博主项目介绍系统分析系统设计数据表设计表4-1:关于我们表4-2:用户表4-3:管理员表表4-4:token表表4-5:系统简介表4-6:收藏…...
ChatGPT能从这几个方面提升学术论文质量
学境思源,一键生成论文初稿: AcademicIdeas - 学境思源AI论文写作 写作和编辑高质量的学术论文是一项具有挑战性的任务。随着人工智能技术的进步,ChatGPT作为一种强大的语言生成工具,正逐渐成为提升论文质量的得力助手。从头脑风…...
Python3的安装及基础指令
Day 20 基础语法 1、环境:python2内置,安装并使用python3,最新版3.12版可以使用源码安装 # 查看python版本号 [rootpython ~]#yum list installed|grep python [rootpython ~]#yum list installed|grep epel [rootpython ~]# yum -y …...
使用Spring与JDK动态代理实现事务管理
使用Spring与JDK动态代理实现事务管理 在现代企业级应用开发中,事务管理是一项关键的技术,它可以保证一系列操作要么全部成功,要么全部失败,从而确保数据的一致性和完整性。Spring框架提供了强大的事务管理能力,但有时…...
服务器硬件及RAID配置
服务器及 RAID 磁盘阵列介绍 RAID0 俗称 “ 条带 ” ,它将两个或多个硬盘组成一个逻辑硬盘,容量是所有硬盘之和,因 为是多个硬盘组合成一个,故可并行写操作,写入速度提高,但此方式硬盘数据没有冗余&#…...
【经验总结】ShardingSphere5.2.1 + Springboot 快速开始
Sharding Sphere 官方文档地址: https://shardingsphere.apache.org/document/current/cn/overview/maven仓库:https://mvnrepository.com/artifact/org.apache.shardingsphere/shardingsphere-jdbc 官方的文档写的很详尽到位,这里会截取部分…...
基于Golang实现Kubernetes边车模式
本文介绍了如何基于 Go 语言实现 Kubernetes Sidecar 模式,并通过实际示例演示创建 Golang 实现的微服务服务、Docker 容器化以及在 Kubernetes 上的部署和管理。原文: Sidecar Pattern with Kubernetes and Go[1] 在这篇文章中,我们会介绍 Sidecar 模式…...
TCP 通信全流程分析:从连接建立到数据传输的深度探索
目录 一、TCP报头 二、三次握手 三、数据传输 四、四次挥手 本文通过一次TCP通信过程的分析来学习TCP协议 一、TCP报头 如图是一份TCP报文的报头,标准报头是20个字节,还可带有选项报头,也就是TCP报头的最小长度是20字节。以下是对报头的各…...
4、提取H264码流中nalu
H264的NALU提取 1、nalu单元 定义nalu的存储单元,ebsp用来存储原始的包含起始码(annexb格式)的原始码流,sodb存储去除防竞争字节后的码流,prefix是3或4字节 nalu_def.h // nalu_def.h #pragma once#include <cs…...
哈佛大学单细胞课程|笔记汇总 (二)
哈佛大学单细胞课程|笔记汇总 (一) (二)Single-cell RNA-seq data - raw data to count matrix 根据所用文库制备方法的不同,RNA序列(也被称为reads或tag)将从转录本((10X Genomic…...
java中抽象类和接口的区别
文章目录 接口和抽象类的区别一、定义的区别1、抽象类2、接口 二、使用场景的区别1、抽象类2、接口 三、使用案例1、抽象类2、接口 接口和抽象类的区别 一、定义的区别 1、抽象类 关键字: abstract 是模棱两可的,似是而非的,无法给出具体明…...
Spring Boot - 在Spring Boot中实现灵活的API版本控制(下)_ 封装场景启动器Starter
文章目录 Pre设计思路ApiVersion 功能特性使用示例配置示例 ProjectStarter Code自定义注解 ApiVersion配置属性类用于管理API版本自动配置基于Spring MVC的API版本控制实现WebMvcRegistrations接口,用于自定义WebMvc的注册逻辑扩展RequestMappingHandlerMapping的类…...
EasyCVR视频转码:T3视频平台不支持GB28181协议,应该如何实现与视频联网平台的对接与视频共享呢?
EasyCVR视频管理系统以其强大的拓展性、灵活的部署方式、高性能的视频能力和智能化的分析能力,为各行各业的视频监控需求提供了优秀的解决方案。 T3视频为公网HTTP-FLV或HLS格式的视频流,目前T3平台暂不支持国标GB28181协议,因此也无法直接接…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...
.Net Framework 4/C# 关键字(非常用,持续更新...)
一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...
ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...
浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求,本次涉及的主要是收费汇聚交换机的配置,浪潮网络设备在高速项目很少,通…...
【Go语言基础【12】】指针:声明、取地址、解引用
文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...
