情不知从何起,一往而情深
排名
6
文章
199
粉丝
4
评论
3
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术

Vue--Vuex 中 Modules 详解

6122人阅读 2023/7/1 9:47 总访问:1106157 评论:0 收藏:0 手机
分类: 前端

前言

  在Vue中State使用是单一状态树结构,应该的所有的状态都放在state里面,如果项目比较复杂,那state是一个很大的对象,store对象也将对变得非常大,难于管理。于是Vuex中就存在了另外一个核心概念 modules。本文就来总结 modules 相关知识点。

正文

1 、什么是模块Modules

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

  1. const moduleA = {
  2. state: () => ({ ... }),
  3. mutations: { ... },
  4. actions: { ... },
  5. getters: { ... }
  6. }
  7. const moduleB = {
  8. state: () => ({ ... }),
  9. mutations: { ... },
  10. actions: { ... }
  11. }
  12. const store = new Vuex.Store({
  13. modules: {
  14. a: moduleA,
  15. b: moduleB
  16. }
  17. })
  18. this.store.state.a // -> 获得moduleA 的状态
  19. this.store.state.b // -> 获得moduleB 的状态

内部state,模块内部的state是局部的,也就是模块私有的,

内部getter,mutation,action 仍然注册在全局命名空间内,这样使得多个模块能够对同一 mutation 或 action 作出响应。

2、模块内部参数问题

对于模块内部的 mutation 和 getter,接收的第一个参数是模块的局部状态对象 state。

对于模块内部的 action,局部状态通过 context.state 暴露出来,根节点状态则为 context.rootState:

对于模块内部的 getter,根节点状态会作为第三个参数暴露出来:

  1. const moduleA = {
  2. state: () => ({
  3. count:"",
  4. }),
  5. actions: {
  6. //这里的state为局部状态,rootState为根节点状态
  7. incrementIfOddOnRootSum ({ state, commit, rootState }) {
  8. if ((state.count + rootState.count) % 2 === 1) {
  9. commit('increment')
  10. }
  11. }
  12. }
  13. mutations: {
  14. // 这里的 `state` 对象是模块的局部状态
  15. increment (state) {
  16. state.count++
  17. }
  18. },
  19. getters: {
  20. //这里的state为局部状态,rootState为根节点状态
  21. doubleCount (state) {
  22. return state.count * 2
  23. },
  24. sumWithRootCount (state, getters, rootState) {
  25. return state.count + rootState.count
  26. }
  27. }
  28. }

3、模块命名空间问题

(1)namespaced: true 使模块成为带命名空间的模块

  当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名。

  1. const store = new Vuex.Store({
  2. modules: {
  3. account: {
  4. namespaced: true,
  5. // 模块内容(module assets) 在使用模块内容(module assets)时不需要在同一模块内额外添加空间名前缀。
  6. state: () => ({}), // 模块内的状态已经是嵌套的了,使用 `namespaced` 属性不会对其产生影响
  7. getters: {
  8. isAdmin() {}, // ->使用: getters['account/isAdmin'],
  9. // 你可以使用 getter 的第四个参数来调用
  10. someGetter(state, getters, rootState, rootGetters) {
  11. // getters.isAdmin
  12. // rootGetters.someOtherGetter
  13. },
  14. },
  15. actions: {
  16. login() {}, // ->使用: dispatch('account/login')
  17. // 你可以使用 action 的第四个参数来调用
  18. //若需要在全局命名空间内分发 action 或提交 mutation,将 { root: true } 作为第三参数传给 dispatch 或 commit 即可
  19. someAction({ dispatch, commit, getters, rootGetters }) {
  20. // getters.isAdmin;
  21. // rootGetters.someGetter;
  22. // dispatch("someOtherAction");
  23. // dispatch("someOtherAction", null, { root: true });
  24. // commit("someMutation");
  25. // commit("someMutation", null, { root: true });
  26. },
  27. someOtherAction(ctx, payload) {},
  28. // 若需要在带命名空间的模块注册全局 action,你可添加 root: true,并将这个 action 的定义放在函数 handler 中。
  29. otherAction: {
  30. root: true,
  31. handler(namespacedContext, payload) {}, // -> 'someAction'
  32. },
  33. },
  34. mutations: {
  35. login() {}, // ->使用: commit('account/login')
  36. },
  37. // 嵌套模块
  38. modules: {
  39. // 继承父模块的命名空间
  40. myPage: {
  41. state: () => ({}),
  42. getters: {
  43. profile() {}, // -> 使用:getters['account/profile']
  44. },
  45. },
  46. // 进一步嵌套命名空间
  47. posts: {
  48. namespaced: true,
  49. state: () => ({}),
  50. getters: {
  51. popular() {}, // -> 使用:getters['account/posts/popular']
  52. },
  53. },
  54. },
  55. },
  56. },
  57. });

(2)带命名空间的绑定函数的使用

  当使用 mapState, mapGetters, mapActions 和 mapMutations 这些函数来绑定带命名空间的模块时,写起来可能比较繁琐:

  1. computed: {
  2. ...mapState({
  3. a: state => state.some.nested.module.a,
  4. b: state => state.some.nested.module.b
  5. })
  6. },
  7. methods: {
  8. ...mapActions([
  9. 'some/nested/module/foo', // -> this['some/nested/module/foo']()
  10. 'some/nested/module/bar' // -> this['some/nested/module/bar']()
  11. ])
  12. }

  createNamespacedHelpers 创建基于某个命名空间辅助函数,它返回一个对象,对象里有新的绑定在给定命名空间 值上的组件绑定辅助函数。

  1. import { createNamespacedHelpers } from 'vuex'
  2. const { mapState, mapActions } = createNamespacedHelpers('some/nested/module')
  3. export default {
  4. computed: {
  5. // 在 `some/nested/module` 中查找
  6. ...mapState({
  7. a: state => state.a,
  8. b: state => state.b
  9. })
  10. },
  11. methods: {
  12. // 在 `some/nested/module` 中查找
  13. ...mapActions([
  14. 'foo',
  15. 'bar'
  16. ])
  17. }
  18. }

4、模块动态注册

  在 store 创建之后,你可以使用 store.registerModule 方法注册模块

  1. import Vuex from 'vuex'
  2. const store = new Vuex.Store({ /* 选项 */ })
  3. // 注册模块 `myModule`
  4. store.registerModule('myModule', {
  5. // ...
  6. })
  7. // 注册嵌套模块 `nested/myModule`
  8. store.registerModule(['nested', 'myModule'], {
  9. // ...
  10. })

之后就可以通过 store.state.myModule 和 store.state.nested.myModule 访问模块的状态。

也可以使用 store.unregisterModule(moduleName) 来动态卸载模块。注意,你不能使用此方法卸载静态模块(即创建 store 时声明的模块)。

可以通过 store.hasModule(moduleName) 方法检查该模块是否已经被注册到 store。

原文:https://www.cnblogs.com/zaishiyu/p/15504057.html


欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739。有需要软件开发,或者学习软件技术的朋友可以和我联系~(Q:815170684)

评价

js与Controller分割字符串的方法

js: varstr=OpenRule; varstrs=newArray(); strs=str.split(","); for(vari=0;i<strs.length;i++){ $(&q...

如何修改CSS存在的element.style内联样式

改腾讯地图的时候调整了下样式,发现样式一直存在问题,修改style里面的值,一点用都没有,html中这个值还找不到是在哪里出...

c、VB.net全角半角转换方法

///<summary> ///转全角的函数(SBCcase) ///</summary> ///<paramname="input">任意字符串...

C.Net 配合小程序实现经过第三方服务器转文件

某些时候,微信小程序前段上传文件的时候需要经过第三方服务器再将文件上传到客户的服务器;操作如下:1:(小程序内向中端服...

Java的堆和栈以及堆栈的区别

在正式内容开始之前要说明一点,我们经常所说的堆栈堆栈是堆和栈统称,堆是堆,栈是栈,合在一起统称堆栈;  1.栈(stack)...

在问题成长感悟

工作中怎么可能不会遇到问题。遇到问题在去解决问题就会变强。就会有独立解决问题的能力就会独挡一面。技术如此,做商务自...

css单位pxem,rem和vh/vw的理解

>px像素(Pixel)。相对长度单位。像素px是相对于显示器屏幕分辨率而言的。em是相对长度单位。相对于当前对象内文本的字...

redis主从、哨兵和集群这三个有什么区别

主从模式:备份数据、负载均衡,一个Master可以有多个Slaves。sentinel(哨兵)发现master挂了后,就会从slave中重新选举一个...

JavaScript的事件委托

什么是事件委托事件委托在JavaScript中是非常常见的,它主要用于对某个元素中的子元素的冒泡事件进行监听。JavaScript高级...

类型“DbSet”在未引用的程序集定义。必须添加对程序集“EntityFramework Version=5.0.0.0 Culture=neutral PublicKeyToken=b7

在用mvc+ef的时候在DAL层引用上下文信息的时候会报出下面错误其实就是没得EntityFromwork,打开vs项目,点击工具,选择NuGe...

SQL Server 使用游标

--声明一个游标 DECLAREMyCursorCURSOR FORSELECTTOP5FBookName,FBookCodingFROMTBookInfo//定义一个叫MyCursor的游标,...

正则表达式匹配文标点符号

//匹配这些中文标点符号。?!,、;:“”‘'()《》〈〉【】『』「」﹃﹄〔〕…—~﹏¥ varreg=/[\u3002|\uff1f|\...

判断table表格checkbox 未选的数据

判断table表格中checkbox 未选中的数据 var arrays = $(table).find("input[name='sel_sw']:not(:checked)&qu...

Oracle数据库没有scott用户

使用SYS用户登录conn sys/密码 as sysdba(默认密码123456)然后找到oracle安装目录下scott.sql的这个文件然后执行命令:@+...

​js截取两个字符间的字符串

使用正则表达式来取比如我们要取brush:js;toolbar:false 这个字符串冒号和分号中间的字符串可以varclassname="brush:j...