vueX的基本使用之Module(终)

本文详细介绍了Vue.js状态管理库Vuex的模块化使用方法,包括如何定义模块、使用命名空间以及如何在组件中访问模块状态等内容。

 

(个人理解:module   例如:购物车模块,订单模块,商品模块...每个模块都有自己的数据)

首先下面的内容是我复制的,我觉得写的还是容易理解的,基本上都看的懂,所以我自己就不重新造轮子了.....

(其实是懒..... )

 

module:可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。

怎么用module?

一般结构

 
const moduleA = {
 state: { ... },
 mutations: { ... },
 actions: { ... },
 getters: { ... }
 }
const moduleB = {
 state: { ... },
 mutations: { ... },
 actions: { ... }
 }

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

 

模块内部的数据:①内部state,模块内部的state是局部的,也就是模块私有的,比如是car.js模块state中的list数据,我们要通过this.$store.state.car.list获取;②内部getter、mutation和action,仍然注册在全局命名空间内,这是为了多模块可以同时响应同一mutation;this.$store.state.car.carGetter的结结果是undefined,而通过this.$store.state.carGetter则可以拿到。

传参:getters====({state(局部状态),getters(全局getters对象),roosState(根状态)});actions====({state(局部状态),commit,roosState(根状态)}).

新建一个项目体验一下,通过vue –cli新建一个项目vuemodule, 不要忘记安装vuex.

1, 在src 目录下新一个login文件夹,在里面新建index.js 用于存放login 模块的状态。 为了简单起见,我把模块下的state, actions,mutations, getters 全放在index.js文件中。

先简单给它增加一个状态,userName: “sam”

const state = {
  useName: "sam"
};
const mutations = {

};
const actions = {

};
const getters = {

};

// 不要忘记把state, mutations等暴露出去。
export default {
  state,
  mutations,
  actions,
  getters
}

 

2,在src 目录下,再新建一个 store.js 这是根store, 它通过modules 属性引入 login模块。

import Vue from "vue";
import Vuex from "Vuex";

Vue.use(Vuex);

// 引入login 模块
import login from "./login"

export default new Vuex.Store({
  // 通过modules属性引入login 模块。
  modules: {
    login: login
  }
})

 

3, 在main.js中引入store, 并注入到vue 根实例中。

import Vue from 'vue'
import App from './App.vue'

// 引入store
import store from "./store"

new Vue({
 el: '#app',
 store, // 注入到根实例中。
 render: h => h(App)
})

 

4,在 app.vue 中通过computed属性获取到login下的state.  这里要注意,在没有modules 的情况下,组件中通过  this.$store.state.属性名  可以获取到,但是有modules 之后,state 被限制到login 的命名空间(模块)下,所以属性名前面必须加模块名(命名空间),组件中通过 this.$store.state.模块名.属性名,在这里是 this.$store.state.login.userName

<template>
 <div id="app">
  <img src="./assets/logo.png">
  <h1>{{useName}}</h1>
 </div>
</template>

<script>
export default {
 // computed属性,从store 中获取状态state,不要忘记login命名空间。
 computed: {
  useName: function() {
   return this.$store.state.login.useName
  }
 }
}
</script>

 

组件中成功获取到状态。项目目录和展示如下

4 ,通过actions, mutations 改变名字, 这就涉及到dispatch action, commit mutations, mutations 改变state.

先在login 文件夹 index.js中添加changeName action 和  CHANGE_NAME  mutations.

const mutations = {
  CHANGE_NAME (state, anotherName) {
    state.useName = anotherName;
  }
};

const actions = {
  changeName ({commit},anotherName) {
    commit("CHANGE_NAME", anotherName)
  }
};

 

在app.vue 中添加一个按钮:<button> change to json</button>, 点击时,dispatch  一个 action. 那在组件中怎么dispatch actions 呢?

在模块中,state 是被限制到模块的命名空间下,需要命名空间才能访问。 但actions 和mutations, 其实还有 getters 却没有被限制,在默认情况下,它们是注册到全局命名空间下的,所谓的注册到全局命名空间下,其实就是我们访问它们的方式和原来没有module 的时候是一样的。比如没有module 的时候,this.$store.dispatch(“actions”), 现在有了modules, actions 也写在了module 下面(changeName 写到了login目录下的index.js中),我们仍然可以这么写,this.$store.dispatch(“changeName”), 组件中的getters, 也是通过 this.$store.getters.module中getters 来获取。

 

<template>
 <div id="app">
  <img src="./assets/logo.png">
  <h1>{{useName}}</h1>
  <!-- 添加按钮 -->
  <div>
   <button @click="changeName"> change to json</button>
  </div>
 </div>
</template>

<script>
export default {
 // computed属性,从store 中获取状态state,不要忘记login命名空间。
 computed: {
  useName: function() {
   return this.$store.state.login.useName
  }
 },
 methods: {

  // 和没有modules的时候一样,同样的方式dispatch action
  changeName() {
   this.$store.dispatch("changeName", "Jason")
  }
 }
}

 

5, 局部参数

虽然dispatch action和 commit mutations 可以全局使用,但是写在module 中的actions, mutations 和getters, 它们获得的默认参数却不是全局的,都是局部的,被限定在它们所在的模块中的。比如mutations和getters 会获得state 作为第一个默认参数,这个state参数,就是限定在mutations 和getters 所在模块的state对象,login 文件夹下的mutations 和getters 只会获取到当前index.js 中的 state 作为参数 。 actions 会获得一个context 对象作为参数,这个context 对象就是当前module 的实例,module 相当于一个小store.

那么怎样才能获取到根store 中的state 和 getters 呢? Vuex 提供了 rootState, rootGetters 作为module 中  getters 中默认参数, actions中context 对象,也会多了两个属性,context.getters, context. rootState,  这些全局的默认参数,都排在局部参数的后面。

我们在store.js中添加 state, getters: 

export default new Vuex.Store({
  // 通过modules属性引入login 模块。
  modules: {
    login: login
  },

  // 新增state, getters
  state: {
    job: "web"
  },
  getters: {
    jobTitle (state){
      return state.job + "developer"
    }
  }
})

 

login 目录下的 index.js

 

app.vue 增加h2 展示 loacaJobTitle, 这个同时证明了getters 也是被注册到全局中的。

<template>
 <div id="app">
  <img src="./assets/logo.png">
  <h1>{{useName}}</h1>

  <!-- 增加h2 展示 localJobTitle -->
  <h2>{{localJobTitle}}</h2>
  <!-- 添加按钮 -->
  <div>
   <button @click="changeName"> change to json</button>
  </div>
 </div>
</template>

<script>
import {mapActions, mapState,mapGetters} from "vuex";
export default {
 // computed属性,从store 中获取状态state,不要忘记login命名空间。
 computed: {
  ...mapState({
   useName: state => state.login.useName
  }),

  // mapGeter 直接获得全局注册的getters
  ...mapGetters(["localJobTitle"])
 },
 methods: {
  changeName() {
   this.$store.dispatch("changeName", "Jason")
  }
 }
}
</script>

 

6, 其实actions, mutations, getters, 也可以限定在当前模块的命名空间中。只要给我们的模块加一个namespaced 属性:

const state = {
  useName: "sam"
};
const mutations = {
  CHANGE_NAME (state, anotherName) {
    state.useName = anotherName;
  }
};
const actions = {
  changeName ({commit, rootState},anotherName) {
    if(rootState.job =="web") {
      commit("CHANGE_NAME", anotherName)
    }
  },
  alertName({state}) {
    alert(state.useName)
  }
};
const getters = {
  localJobTitle (state,getters,rootState,rootGetters) {
    return rootGetters.jobTitle + " aka " + rootState.job
  }
};
// namespaced 属性,限定命名空间
export default {
  namespaced:true,
  state,
  mutations,
  actions,
  getters
}

 

当所有的actions, mutations, getters 都被限定到模块的命名空间下,我们dispatch actions, commit mutations 都需要用到命名空间。如 dispacth("changeName"),  就要变成 dispatch("login/changeName"); getters.localJobTitle 就要变成 getters["login/localJobTitle"]

app.vue 如下:

<template>
 <div id="app">
  <img src="./assets/logo.png">
  <h1 @click ="alertName">{{useName}}</h1>

  <!-- 增加h2 展示 localJobTitle -->
  <h2>{{localJobTitle}}</h2>
  <!-- 添加按钮 -->
  <div>
   <button @click="changeName"> change to json</button>
  </div>
 </div>
</template>

<script>
import {mapActions, mapState,mapGetters} from "vuex";
export default {
 // computed属性,从store 中获取状态state,不要忘记login命名空间。
 computed: {
  ...mapState("login",{
   useName: state => state.useName
  }),

   localJobTitle() {
    return this.$store.getters["login/localJobTitle"]
   }
 },
 methods: {
  changeName() {
   this.$store.dispatch("login/changeName", "Jason")
  },
  alertName() {
   this.$store.dispatch("login/alertName")
  }
 }
}
</script>

 

有了命名空间之后,mapState, mapGetters, mapActions 函数也都有了一个参数,用于限定命名空间,每二个参数对象或数组中的属性,都映射到了当前命名空间中。

<script>
import {mapActions, mapState,mapGetters} from "vuex";
export default {
 computed: {
  // 对象中的state 和数组中的localJobTitle 都是和login中的参数一一对应。
  ...mapState("login",{
   useName: state => state.useName
  }),
  ...mapGetters("login", ["localJobTitle"])
 },
 methods: {
  changeName() {
   this.$store.dispatch("login/changeName", "Jason")
  },
  ...mapActions('login', ['alertName'])
 }
}
</script>

 

 

好了,合适自己的才是好的。。。。太深奥的东西就没必要了(那是建立在实践经验中的)这个vueX基本上是完了,之后我就该写 vue-router了。。。       

 

会点php的前端小渣渣

               

<think>好的,我现在需要帮助用户了解如何在Vue.js中使用Vuex模块(module)。首先,我需要回忆一下Vuex基本概念,以及模块化的作用。根据用户提供的引用内容,Vuex模块主要用于管理大型应用中的状态,将store分割成多个模块,每个模块有自己的state、mutations、actions和getters,这样可以更好地组织代码。 接下来,我需要按照用户的要求,结构清晰地分步骤解释使用方法。首先应该介绍模块化的基本概念和作用,然后是如何创建模块,接着是注册模块到主store中,之后是模块的局部状态和访问方式,最后是命名空间的使用。同时,需要引用用户提供的参考资料来支持每个步骤,确保回答的真实可靠。 在开始组织内容时,需要确保所有行内数学表达式(如果有的话)使用$...$格式,但考虑到这是一个关于Vuex的技术问题,可能不需要数学公式。但如果有代码示例,需要正确使用代码块,并遵循用户提供的格式示例,比如Python代码的展示方式。不过Vuex通常是使用JavaScript,所以需要调整代码示例为JavaScript语法。 用户还要求生成相关问题,所以需要最后列出几个相关问题,帮助用户进一步学习。同时,回答中引用的内容需要自然地添加引用标识,例如在提到模块的作用时引用[^1],在注册模块时引用[^2]等。 需要注意的是,用户提供的引用中有一些关于Vuex模块的具体代码示例,比如在store.js中引入模块,并导出创建store的函数。这些代码示例需要被正确引用,并解释清楚步骤。例如,如何导入模块,如何在Vuex.Store的modules选项中注册它们,以及如何在组件中访问模块的状态、提交mutations和分发actions。 另外,用户提到模块的局部状态和rootState、rootGetters的使用,这部分需要详细说明如何在模块内部访问根状态,以及如何在组件中访问不同模块的状态。同时,命名空间的概念也很重要,需要解释默认情况下模块的全局命名空间和如何启用命名空间来避免命名冲突。 可能还需要提醒用户关于模块的动态注册和卸载,但根据提供的引用内容,可能没有相关信息,所以可能不需要涉及,除非必要。如果有不确定的地方,应该避免猜测,而是基于提供的引用材料来回答。 最后,确保整个回答结构清晰,步骤分明,每个部分都有对应的引用支持,并且语言简洁易懂,符合中文表达习惯。检查是否有遗漏的步骤,比如模块的创建、注册、访问方式、命名空间配置等,确保覆盖用户可能需要的所有关键点。</think>### Vuex模块使用方法分步说明 #### 一、模块化基本概念 Vuex模块允许将大型应用的状态管理拆分为独立模块,每个模块包含自身的$state$、$mutations$、$actions$和$getters$。这种方式能有效解决状态命名冲突问题,提升代码可维护性[^1][^3]。 #### 二、创建模块 1. **定义模块结构** 每个模块是一个包含状态管理四要素的独立对象: ```javascript // moduleA.js export default { state: { count: 0 }, mutations: { increment(state) { state.count++ } }, actions: { asyncIncrement({ commit }) { setTimeout(() => commit('increment'), 1000) } }, getters: { doubleCount: state => state.count * 2 } } ``` #### 三、注册模块 2. **主Store集成** 在Vuex主文件中通过$modules$选项注册: ```javascript // store.js import Vuex from 'vuex' import moduleA from './moduleA' import moduleB from './moduleB' export default new Vuex.Store({ modules: { moduleA, // 简写形式 moduleA: moduleA moduleB } }) ``` 引用示例来自实际项目配置[^2] #### 四、模块状态访问 3. **组件中调用** - **状态访问**:通过模块路径访问 ```javascript this.$store.state.moduleA.count ``` - **提交变更**:需包含模块名前缀 ```javascript this.$store.commit('moduleA/increment') ``` - **分发动作**: ```javascript this.$store.dispatch('moduleA/asyncIncrement') ``` 完整调用方式参见官方实践[^4] #### 五、模块高级特性 4. **局部上下文访问** 在模块内部: ```javascript actions: { localAction({ state, commit, rootState }) { // state: 模块局部状态 // rootState: 全局状态 } } ``` 支持通过$rootState$访问全局状态[^2] 5. **命名空间配置** 默认情况下模块的$actions/mutations$会注册到全局命名空间。通过添加$namespaced: true$启用隔离: ```javascript export default { namespaced: true, state: { /* ... */ }, // 其他属性自动成为命名空间限定 } ``` #### 六、完整流程示例 ```mermaid graph TD A[创建模块对象] --> B[主Store注册模块] B --> C[组件访问模块状态] C --> D[提交模块级mutation] D --> E[触发状态变更] ```
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值