Vuex 状态管理的基本使用配置

![vuex流程图](https://upload-images.jianshu.io/upload_images/27099288-a1b6ade4416af486.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ### 1.安装Vue 依赖包 `npm install vuex@3 --save` vue2 只能用vuex的3版本 vue3 只能用vuex的4版本 `npm view vuex versions` 查看vuex所有版本 ### 2.创建 store `src`目录下 新建 `store` 目录 ,创建 `index.js` 文件 ``` // 引入 vue import Vue from 'vue' // 引入 vuex import Vuex from 'vuex' // 使用Vuex Vue.use(Vuex) // 用于存储数据 const state = {} // 用于响应组件中的动作 const actions = {} // 用于操作数据(state) const mutations = {} // 创建store const store = new Vuex.Store({ state, mutations, actions }) // 导出 store export default store; ``` ### 3.引入store main.js 中 引入 `import store from './store'` 配置 store ```vue new Vue({ el: '#app', render:h => h(App), router, //将创建的共享数据对象,挂载在vue实例中 //所有的组件,就可以直接从store中获取全局的数据了 store }) ``` # Vuex 应用 ## state **作用**:获取数据 **获取state数据的第一种方式** : ``` this.$store.state.全局数据名称 ``` **第二种方式** : 从vuex中按需导入mapState 函数 ``` import { mapState } from 'vuex' ``` 通过刚才导入的mapState 函数,将当前组件需要的全局数据,映射为当前组件的computed计算属性 ``` computed: { //数组写法 count 是store中全局共享数据名称 获取store中的数据 ...mapState(['count']) // 对象写法 ...mapState({count:'count',...}) } ``` ### mutations **作用:**修改全局state中的数据(用于操作数据) 只能 通过 `mutations` 修改 `state` 中的数据,可以集中监控所有数据的变化。不可以直接操作 `store` 中的数据。 `mutations`里面方法名称一般大写,方法第一个参数永远都是一个 `state` 代表全局对象,直接`state.`属性就可以调用全局共享数据的属性, ```js const mutations = { // value 参数 INCRE(state, value) { state.sum += value }, DECRE(state, value) { state.sum -= value } } ``` **触发mutation 的第一种方式** **不传参数:**`this.$store.commit('方法名')` add 是Mutation中定义的函数名 **传参数 :** `this.$store.commit('方法名',参数)` **触发mutation 的第二种方式** 从 `vuex` 中按需导入 `mapMutations` 函数 ``` import { mapMutations } from 'vuex' ``` 通过刚才导入的 `mapMutations` 函数,将需要的 `mutations`,映射为当前组件的 `methods` 方法 ``` methods: { // 数组写法 吧全局mutations里面的sub、subN函数映射为当前组件的methods (如果有参数需要触发的时候传过来) ...mapMutations(['sub', 'subN']), // 对象写法 (如果有参数需要触发的时候传过来) ...mapMutations({sub:'sub', subN:'subN'}), } this.sub();//可以直接调用 this.subN();//可以直接调用 ``` **注意:在 `mutations` 中不要执行异步操作,`mutations`里面只处理简单方法,没有业务逻辑的** ### actions **作用:**用于处理异步任务 如果通过异步操作变更数据,必须通过 `action` ,而不能使用 `Mutation`,但是在 `Action` 还是要通过触发 `Mutation` 的方式间接变更数据 `action`方法第一个参数永远都是一个 `context` 相当于new出来的 `store` 的实体对象 修改state中的数据必须通过 `mutations` **触发Actions 的第一种方式** ``` this.$store.dispatch('方法名') //addAsync adction中的函数 dispatch函数 专门用来触发 action ``` **触发Actions 的第二种方式** 从vuex中按需导入 `mapActions` 函数 ``` import { mapActions } from 'vuex' ``` 通过刚才导入的 `mapActions` 函数,将需要的 `actions` 函数 ,映射为当前组件的methods方法 ``` methods: { // 数组方式 (方法名称必须和vuex里面的方法相同) ...mapActions(['方法名1', '方法名2']) // 对象方式 ...mapActions({ 方法名1: 'action里面的方法名1',方法名2: 'action里面的方法名2' }) } ``` ### getters **作用:** 包装作用,不会修改数据(用于 state 中数据加工) 在getters中定义一个函数 ``` //定义函数 showNum(state) { return '当前最新数据是[' + state.count + ']' } ``` **使用getters第一种方式** ``` this.$store.getters.名称 this.$store.getters.showNum ``` **使用getters第二种方式** 从vuex中按需导入 `mapGetters` 函数 ``` //组件访问state中数据的第二种方式 先导入 import { mapGetters } from 'vuex'; ``` 通过刚才导入的mapGetters函数,将当前组件需要的全局数据,映射为当前组件的computed计算属性 ``` computed: { // 数组写法(方法名称必须和vuex里面的方法相同) ...mapGetters(['方法名']), // 对象写法 ...mapGetters({ 方法名: 'getter里面的方法名称' }) } ``` * * * # vuex 模块化+命名空间 > 目的:代码更好维护,让多种类数据更加明确 **开启命名空间后,读取 state 数据** ```js this.$store.state.countAbout.sum // 直接的读取 ...mapState('countAbout', ["sum", "school", "subject"]) // 借助mapState读取 ``` **开启命名空间后,读取 getters 数据** ```js this.$store.getters[countAbout/bigSum] // 直接的读取 ...mapGetters('countAbout', ['bigSum']) //借助mapGetters读取 ``` **开启命名空间后,读取 dispatch 数据** ```js this.$store.dispatch('countAbout/increOdd', val) // 直接的读取 ...mapActions('countAbout', { handleIncreOdd: 'increOdd', handleIncreWait: 'increWait' }) // 借助 mapActions 读取 ``` **开启命名空间后,读取 commit 数据** ```js this.$store.commit('countAbout/INCRE', val) // 直接的读取 ...mapMutations('countAbout', { handleIncre: 'INCRE', handleDecre: 'DECRE' }) // 借助 mapMutations 读取 ``` **store/index.js** ```js import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) import countOptions from "./modules/count" import personOptions from "./modules/person" // 创建store并导出 store export default new Vuex.Store({ modules: { countAbout: countOptions, personAbout: personOptions } }) ``` **store/modules/count.js** ![count.js](https://upload-images.jianshu.io/upload_images/27099288-0ca66b91e0201546.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ### Demo1 ==> 计数 Count.vue ```vue
{{sum}}

getters:{{bigSum}}

{{school}}, {{subject}}

+2 -3 奇数加1 1s后+1
``` stores/index.js ```js // 引入 vue import Vue from 'vue' // 引入vuex import Vuex from 'vuex' Vue.use(Vuex) // 用于存储数据 const state = { sum: 0, school: 'ans', subject: 'web' } // 用于操作数据(state) const mutations = { INCRE(state, value) { state.sum += value }, DECRE(state, value) { state.sum -= value } } // 用于响应组件中的动作 const actions = { increOdd(context, value) { if (context.state.sum % 2) { context.commit('INCRE', value) } }, increWait(context, value) { setTimeout(() => { context.commit('INCRE', value) }, 1000); } } // 用于 state 中数据加工 const getters = { bigSum(state) { return state.sum * 10 } } // 创建store并导出 store export default new Vuex.Store({ state, mutations, actions, getters }) ``` ### Demo2 ==> 计算小例子 #### **main.js** ``` import Vue from 'vue' import App from './App' import router from './router' import store from './store' Vue.config.productionTip = false // new Vue({ // el: '#app', // router, // components: { App }, // template: '' // }) new Vue({ el: '#app', render:h => h(App), router, //将创建的共享数据对象,挂载在vue实例中 //所有的组件,就可以直接从store中获取全局的数据了 store }) ``` #### **store.js** ``` import { subset } from 'semver' import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ //state中存放的就是全局共享的数据 state: { //全局count值為0 count: 0 }, mutations: { //定义一个add函数 第一个参数永远都是一个state 代表全局对象 //加1 add(state) { state.count++ }, //加N addN(state, step) { state.count += step }, //减1 sub(state) { state.count-- }, //减N subN(state, step) { state.count -= step } }, actions: { //异步操作 context相当于new 出来的store的实体对象 addAsync(context) { setTimeout(() => { //修改state中的数据必须通过mutations context.commit('add') }, 2000) }, //等会2秒异步加N addAsyncN(context, step) { setTimeout(() => { //修改state中的数据必须通过mutations context.commit('addN', step) }, 2000) }, //等待2秒异步减1 subAsync(context) { setTimeout(() => { //修改state中的数据必须通过mutations context.commit('sub') }, 2000) }, //等待2秒异步减N subAsyncN(context, step) { setTimeout(() => { //修改state中的数据必须通过mutations context.commit('subN', step) }, 2000) } }, getters: { //定义函数 showNum(state) { return '当前最新数据是[' + state.count + ']' } } }) ``` #### addition.vue 加法组件 ```

当前最新的count值为:{{ $store.state.count }}

getter包装的:{{ $store.getters.showNum }}

+1 +3 等待2秒异步+1 等待2秒异步+10
``` #### subtraction.vue 减法组件 ```

当前最新的count值为:{{ count }}

getter包装的:{{ showNum }}

-1 -3 等待2秒异步-1 等待2秒异步-10
``` #### App.vue 跟组件 ```

-------------------------------------------

``` 效果图如下: ![测试.png](https://upload-images.jianshu.io/upload_images/27099288-b00d2a8b013163dd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

你可能感兴趣的:(Vuex 状态管理的基本使用配置)