Vue@2.x系列之状态管理模式(Vuex)

1. 概述

Vuex 是专门给vue.js使用的状态管理器,其基本作用是为了解决中大型单页应用中组件之间的通信问题。
Vuex主要包括三个核心内容,state(Vue组件的数据),actions(可执行异步代码),mutations(修改state中的数据)。三者之间的关系如下图(该图片来自于官网
在这里插入图片描述
Vuex的核心是store(仓库),储存着应用中大部分state(状态),state的特点如下:

  1. state是响应式的,如果state发生变化,那么对应的组件会随之更新。
  2. state不能直接修改,必须通过提交mutation来修改。

2. 快速开始

2.1 安装

npm i vuex --save

2.2 模块化使用

2.2.1 目录结构

在这里插入图片描述

2.2.2 mutation-types.js

该文件中包含mutation类型的常量文件。该文件并不是必须的,是否使用取决同时开发项目的成员有多少。如果人员较多可以使用。

export const ADD_LIST = 'ADD_LIST';
export const DELETE_LIST_ITEM = 'DELETE_LIST_ITEM';

2.2.3 mutations.js

导出一个包含一系列可以直接修改state的方法。

import { ADD_LIST } from "./mutation-types";

export default {
    // 添加列表项
	[ADD_LIST](state) {
		state.list = [ ...state.list, `list${state.list.length}`];
	}
}
  1. mutations对象中的方法包含两个参数:
    - state — Vuex中的state
    - payload — 提交mutation时传入的参数
  2. 提交mutation:
    只能以载荷的方式提交mutation。
store.commit('mutationType', 'somePayload');

2.2.4 actions.js

导出一个包含一些列可以执行异步操作的方法。虽然能够在组件中直接触发action,并且action中也能直接访问到state,但是action中不能直接修改state,如果像修改state,必须调用commit提交mutation,在mutation中修改state。

import { ADD_LIST } from "./mutation-types";

export default {
	asyncAdd(context) {
		setTimeout(() => {
			context.commit(ADD_LIST);
		}, 2000);
	}
}
  1. actions对象中的方法两个参数
    - context — context是和store实例具有相同属性和方法的上下文对象。
    - payload — 触发action时传入的参数。

context是和store实例具有相同属性和方法的上下文对象,所以,

  1. action中能够访问state;
  2. action中能够触发其他action;
  3. action中能够提交mutation;
  4. action中能够访问getters,和组件中的计算属性类似。
  1. 触发action
// 以载荷形式触发
store.dispatch('incrementAsync', {
  amount: 10
})

// 以对象形式触发
store.dispatch({
  type: 'incrementAsync',
  amount: 10
})

2.2.5 getters.js

getters和组件的计算属性computed类似。

export default {
	increase(state) {
		return ++state.count;
	}
}

2.2.5 store/index.js

import Vue from 'vue';
import Vuex from 'vuex';
import mutations from './mutations.js';
import actions from './actions.js';
import getters from './getters.js';

Vue.use(Vuex);

export default new Vuex.Store({
	state: {
		part: 'root',
		count: 0,
		list: ['list0', 'list1', 'list2']
	},
	mutations,
	actions
	getters
});

2.3 src/main.js

将store实例添加到vue实例中,以便实例下的所有组件可以直接通过 this.$store 获取store实例。

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

new Vue({
  store,
  render: h => h(App),
}).$mount('#app');

2.4 src/App.vue

<template>
  <div id="app">
    <span>测试Vuex</span>
    <div class="store-box">
      {{partName}}
      <br>
      increase: {{increase}}
      <br>
      <button @click="addList">添加</button>
      <ul>
        <li v-for="(item, index) in list" :key="index">
          {{`${item}, ${index}`}}
        </li>
      </ul>
    </div>
  </div>
</template>

<script>
import { ADD_LIST } from './store/mutation-types';
import { mapState, mapGetters } from 'vuex';

export default {
  name: 'App',
  data() {
  	return {}
  },
  computed: {
  	partName() {
  		return this.$store.state.part;
    },
	list() {
  		return this.$store.state.list;
    },
    increase() {
  		return this.$store.getters.increase;
    }
  },
  methods: {
  	// 点击添加按钮,提交mutation
  	addList() {
		this.$store.commit(ADD_LIST);
    }
  }
}
</script>

2.5 页面效果

在这里插入图片描述

点击添加按钮之后的效果:
在这里插入图片描述

3. 辅助函数

使用辅助函数获取vuex中的属性或者方法:

import { mapState, mapGetters } from 'vuex';

export default {
	...,
	computed: {
	  	...mapState({partName: 'part', list: 'list'}),
	    ...mapGetters(['increase', 'decrease'])
	},
	methods: {
		...mapActions([
	      'increment', // 将 `this.increment()` 映射为 `this.$store.dispatch('increment')`
	
	      // `mapActions` 也支持载荷:
	      'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.dispatch('incrementBy', amount)`
	    ]),
	    ...mapActions({
	      add: 'increment' // 将 `this.add()` 映射为 `this.$store.dispatch('increment')`
	    }),
	    ...mapMutations([
	      'increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment')`
	
	      // `mapMutations` 也支持载荷:
	      'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.commit('incrementBy', amount)`
	    ]),
	    ...mapMutations({
	      add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')`
	    })
	}
	...
]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值