深入理解Vuex 模块化(module)

深入理解Vuex 模块化(module)

背景介绍

Vue.js 是目前广泛应用于前端开发中的一款 JavaScript 框架。它的状态管理工具——Vuex, 大大减轻了开发者在组件之间共享数据时的繁琐操作,让数据流变得简单、易于维护、减少错误。那么如何更好地利用Vuex,使得你的代码更好的进行管理呢?这就需要深入理解Vuex模块化。

什么是Vuex 模块化(module)

在大型项目中,我们可以将 Vuex 的状态划分为多个模块。同一个模块可以有自己的 state、mutations、actions、getters等属性,同时这些属性也可以被其他模块访问,实现了模块化的效果。从而对于大型应用来说,这些模块组成一个完整的状态树,便于统一管理。

模块化开发的两种方式

Vuex 支持两种方式来进行模块化的开发:

方式一:直接使用模块内的属性的命名空间

命名空间是一个对象,该对象会与父模块的命名空间进行合并。这意味着,嵌套模块可以使用模块的全局命名空间,或者使用它们自己的本地命名空间。

const store = new Vuex.Store({
  modules: {
    account: {
      namespaced: true, // 开启命名空间
      state: {
        name: 'Tom',
        age: 18
      },
      mutations: {
        updateName(state, newName) {
          state.name = newName
        },
        updateAge(state, newAge) {
          state.age = newAge
        }
      },
      actions: {
        updateInfo({commit}, {name, age}) {
          return new Promise(resolve => {
            setTimeout(() => {
              commit('updateName', name)
              commit('updateAge', age)
              resolve()
            }, 1000)
          })
        }
      }
    }
  }
})

// 在组件使用时,在属性名称之前加上命名空间的名称
computed: {
  ...mapState({
    name: state => state.account.name,
    age: state => state.account.age
  })
},

methods: {
  ...mapActions('account', ['updateInfo'])
}

方式二:使用模块的嵌套属性来进行命名空间的操作

Vuex 还支持使用模块的嵌套属性来进行命名空间的操作。在这种模式下,我们可以使用命名空间的目录结构来查找模块的缩写。

// 定义子模块
const moduleA = {
  state: { ... },
  mutations: { ... },
  actions: { ... },
  modules: { /* 子模块嵌套 */ }
}

// 定义 store
const store = new Vuex.Store({
  modules: {
    // 自动命名空间
    a: {
      state: { ... },
      mutations: { ... },
      actions: { ... },
      modules: {
        // 自动命名空间
        subModule: {
          state: { ... },
          mutations: { ... },
          actions: { ... }
        }
      }
    }
  }
})

// 在组件使用时,直接按照嵌套的层次调用属性即可
computed: {
  ...mapState({
    A: state => state.a.someProp,
    subA: state => state.a.subModule.someProp
  })
}

示例

示例一:嵌套模块

const store = new Vuex.Store({
  modules: {
    user: {
      namespaced: true, // 开启命名空间
      state: {
        name: 'Tom',
        age: 18
      },
      getters: {
        getName: state => state.name,
        getAge: state => state.age
      },
      mutations: {
        updateName(state, newName) {
          state.name = newName
        },
        updateAge(state, newAge) {
          state.age = newAge
        }
      },
      actions: {
        updateInfo({commit}, {name, age}) {
          return new Promise(resolve => {
            setTimeout(() => {
              commit('updateName', name)
              commit('updateAge', age)
              resolve()
            }, 1000)
          })
        }
      },
      modules: {
        info: {
          namespaced: true,
          state: {
            detail: 'This is the user information module.'
          },
          mutations: {
            updateDetail(state, newDetail) {
              state.detail = newDetail
            }
          },
          getters: {
            getDetail: state => state.detail
          }
        }
      }
    }
  }
})

// 在组件使用时,在属性名称之前加上命名空间的名称
computed: {
  ...mapState({
    name: state => state.user.name,
    age: state => state.user.age,
    detail: state => state.user.info.detail
  }),

  ...mapGetters('user', ['getName', 'getAge', 'info/getDetail'])
},

methods: {
  ...mapActions('user', ['updateInfo']),

  ...mapMutations('user', ['updateName', 'updateAge', 'info/updateDetail'])
}

示例二:分层模块

const store = new Vuex.Store({
  modules: {
    common: {
      namespaced: true,
      state: {
        loading: false,
        error: null
      },
      mutations: {
        showLoading(state) {
          state.loading = true
        },
        hideLoading(state) {
          state.loading = false
        },
        showError(state, error) {
          state.error = error
        },
        clearError(state) {
          state.error = null
        }
      },
      getters: {
        isLoading: state => state.loading,
        getError: state => state.error
      }
    },

    user: {
      namespaced: true,
      state: {
        name: 'Tom',
        age: 18
      },
      mutations: {
        updateName(state, newName) {
          state.name = newName
        },
        updateAge(state, newAge) {
          state.age = newAge
        }
      },
      actions: {
        fetchUserInfo({commit, dispatch}) {
          commit('common/showLoading', null, { root: true }); // 访问全局命名空间方法的方式

          return getUserInfo().then(res => {
            commit('updateName', res.name)
            commit('updateAge', res.age)
          },error => {
            commit('common/showError', error.message, { root: true });
            dispatch('reset', null, { root: true }); // 调用全局命名空间下的其他action
          }).finally(() => {
            commit('common/hideLoading', null, { root: true });
          })
        },
        reset({commit, dispatch}) {
          commit('updateName', 'Tom')
          commit('updateAge', 18)
          dispatch('common/clearError', null, { root: true }); // 调用全局命名空间下的其他mutation
        }
      }
    }
  }
})

// 在组件使用时,在属性名称之前加上命名空间的名称
computed: {
  ...mapState({
    name: state => state.user.name,
    age: state => state.user.age,
    isLoading: state => state.common.loading,
    error: state => state.common.error
  }),
  ...mapGetters('common', ['isLoading', 'getError'])
},

methods: {
  ...mapActions('user', ['fetchUserInfo', 'reset']),

  ...mapMutations('user', ['updateName', 'updateAge']),

  ...mapMutations('common', ['showLoading', 'hideLoading', 'showError', 'clearError'])
}

总结

通过以上示例,相信大家已经对Vuex的模块化有了深入了解。使用Vuex模块化,可以让我们的代码变得更加清晰易懂,分工更加明确,同时也更加方便地维护代码。在实际开发的过程中,可以结合实际业务需求,巧妙运用Vuex模块化进行状态管理,提高代码质量。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:深入理解Vuex 模块化(module) - Python技术站

(0)
上一篇 2023年5月28日
下一篇 2023年5月28日

相关文章

  • 京东 Vue3 组件库支持小程序开发的详细流程

    以下是详细讲解“京东 Vue3 组件库支持小程序开发的详细流程”的完整攻略: 1. 准备工作 在开始开发之前,需要先准备好以下工作: 首先安装 Node.js (大于v10.13)和 yarn。 新建一个 Vue3 项目,使用 Vue CLI 搭建,并且安装好小程序开发的相关依赖。 2. 下载并安装组件库 京东 Vue3 组件库已经支持小程序开发,我们可以直…

    Vue 2023年5月27日
    00
  • 简单的vuex 的使用案例笔记

    下面我将为你详细讲解“简单的vuex的使用案例笔记”的完整攻略。 一、什么是Vuex? Vuex是Vue.js的官方状态管理工具,由于Vue.js是一款轻量级的前端框架,因此Vuex可以很好地解决多组件共享状态管理的问题,让我们可以更方便地管理组件之间的通信问题。 二、安装和配置Vuex 1.安装 你可以通过npm或者yarn安装Vuex: npm inst…

    Vue 2023年5月28日
    00
  • vue使用echarts图表的详细方法

    当我们需要在Vue项目中使用Echarts图表时,需要进行以下步骤: 安装echarts和vue-echarts 使用npm或yarn安装: npm install echarts vue-echarts yarn add echarts vue-echarts 在Vue项目中引入echarts和vue-echarts 在需要使用Echarts图表的Vue组…

    Vue 2023年5月29日
    00
  • Vue计算属性与监视(侦听)属性的使用深度学习

    下面是关于Vue计算属性和监视属性的使用深度学习的完整攻略: 什么是Vue计算属性和监视属性 在Vue中,我们可以使用计算属性和监视属性来处理数据和响应数据的变化。 计算属性:通常用来根据已有的数据计算出新的数据。可以缓存计算结果,避免重复计算的开销。在数据变化时,它会自动更新计算结果,也可以手动调用它来更新计算结果。 监视属性:用来监听某个数据的变化,当指…

    Vue 2023年5月28日
    00
  • 微信js-sdk地理位置接口用法示例

    下面我会分为几个部分讲解“微信js-sdk地理位置接口用法示例”的完整攻略。 一、前置条件 在使用微信js-sdk地理位置接口之前,需要确保以下几个条件已经满足: 已经在微信公众平台中配置了JS接口安全域名。 已经在页面中引入微信公众平台提供的js文件(如:http://res.wx.qq.com/open/js/jweixin-1.4.0.js)。 已经申…

    Vue 2023年5月28日
    00
  • vue项目每30秒刷新1次接口的实现方法

    实现Vue项目每30秒刷新1次接口可以通过以下步骤完成: 安装axios库 可以通过以下命令安装axios: npm install axios –save 在Vue项目中创建一个Data对象来保存需要更新的数据 data() { return { data: [] } } 在Vue的Mounted生命周期钩子函数中初始化请求数据 mounted() { …

    Vue 2023年5月29日
    00
  • Vue3 源码导读(推荐)

    下面就详细讲解一下“Vue3 源码导读(推荐)”的完整攻略。 概述 在Vue.js开发过程中,我们都知道Vue.js是一个非常好用的MVVM框架,而Vue.js3的发布也备受关注。Vue.js 3.0采用完全重写的方式,核心代码相比2.x版本变化较大,提高了性能。 导读 为了能够更好地学习Vue.js 3.0,我们需要先了解Vue.js 3.0的源码结构和架…

    Vue 2023年5月27日
    00
  • Vue使用formData格式类型上传文件的示例

    下面是“Vue使用formData格式类型上传文件的示例”的完整攻略。 1. 什么是formData格式类型上传文件 在前端上传文件时,一般需要将文件的二进制数据转换为一种可被后端接收的格式,最常用的格式有form-data和base64编码。其中最常用的方法是使用form-data格式。formData格式是一种键值对的格式,每一个键对应一个值,值可以是字…

    Vue 2023年5月28日
    00
合作推广
合作推广
分享本页
返回顶部