一篇搞定Vuex

1.简介

  首先,你必须明显明白vuex到底是干啥的,主要解决开发中的哪些问题?

  Vuex是一个专门为Vue.js应用程序开发的状态管理模式,它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式变化

  说白了,就是:提供了那么一个公共存储的地方,存放各个组件的数据,组件访问数据和操作数据访问这个地方即可

  所以,Vuex主要解决是组件间数据传递问题,尤其是嵌套组件,项目一大时,父子组件间的数据传递就非常麻烦了,而Vuex则提供了一种集中管理组件数据的方案,当然小型项目就没必要用Vuex了

 

2.Demo准备

  • vue init webpack-simple vuex-demo
  • cd vuex-demo
  • npm install
  • npm install vuex -S

 

3.访问store对象的两种方式  

  Vuex的核心是Store(仓库),相当于是一个容器,一个store实例中包含以下属性的方法:

  • state  定义属性(状态、数据)
  • getters  用来获取属性
  • actions  定义方法(动作)
  • commit  提交变化,修改数据的唯一方式就是显式的提交mutations
  • mutations  定义变化

  注:不能直接修改数据,必须显式提交变化,目的是为了追踪到状态的变化

 

  创建store.js文件,在main.js中导入并配置store.选项

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex);

//定义属性(数据)
var state = {
  count: 6
}


//创建store对象
const store = new Vuex.Store({
  state,
})

//导出store对象
export default store;
import Vue from 'vue'
import App from './App.vue'

import store from './store.js'  //导入store对象

new Vue({
  store,
  el: '#app',
  render: h => h(App)
})

 

  方式一:通过this.$store访问

  //方式1:通过this.$store访问
  computed: {
    count() {
      return this.$store.state.count;
    }
  }

  方式二:通过mapState、mapGetters、mapActions访问,vuex提供了两个方法

  • mapState  获取state
  • mapGetters  获取getters
  • mapActions  获取actions
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex);

//定义属性(数据)
var state = {
  count: 6
}

//定义getters
var getters = {
  count(state) {
    return state.count;
  }
}

//定义actions,要执行的操作,如流程判断、异步请求
const actions = {
  increment(context) { //包含 commit dispatch state
    context.commit('increment');
  },
  decrement(context) {
    if (context.state.count > 10) {
      context.commit('decrement');
    }
  }
}

//定义mutations,处理状态(数据)的改变
const mutations = {
  increment(state) {
    state.count++;
  },
  decrement(state) {
    state.count--;
  }
}

//创建store对象
const store = new Vuex.Store({
  state,
  getters,
  actions,
  mutations,
})

//导出store对象
export default store;

 

<template>
  <div id="app">
    <button @click="increment">增加</button>
    <button @click="decrement">减小</button>
    <p>当前数字为:{{count}}</p>
  </div>
</template>

<script>
import { mapState, mapGetters, mapActions } from "vuex";

export default {
  name: "app",
  data() {
    return {
      msg: "Welcome to Your Vue.js App"
    };
  },
  //方式1:通过this.$store访问
  /*computed: {
    count() {
      return this.$store.state.count;
    }
  }*/

  /*computed:mapState([
    'count'
  ])*/

  computed: mapGetters(["count"]),
  methods:mapActions([
    'increment',
    'decrement',
  ])
};
</script>

<style>
</style>

  

分模块组织Vuex

  上面那种方式,所有的都写在一个文件,项目大时,难免看起来显乱,所以需要分模块来组织,原则上就私有和公共的分开进行组织

  其中modules存放每个模块的,actions.js,getters.js,mutations.js存放公共的,目录如下

user.js

/**
 * 用户模块
 */

import types from '../types.js'

 const state={
 	count:6
 }

var getters={
	count(state){
		return state.count;
	}
}

const actions = {
	increment({commit,state}){
		commit(types.INCREMENT); //提交一个名为increment的变化,名称可自定义,可以认为是类型名
	},
	decrement({commit,state}){
		if(state.count>10){
			commit(types.DECREMENT);
		}
	}
}

const mutations={
	[types.INCREMENT](state){
		state.count++;
	},
	[types.DECREMENT](state){
		state.count--;
	}
}

export default {
	state,
	getters,
	actions,
	mutations
}

  

actions.js

import types from './types.js'

const actions={
	incrementAsync({commit,state}){
		//异步操作
		var p=new Promise((resolve,reject) => {
			setTimeout(() => {
				resolve();
			},3000);
		});

		p.then(() => {
			commit(types.INCREMENT);
		}).catch(() => {
			console.log('异步操作');
		});
	}
}

export default actions;

  

getters.js

const getters={
	isEvenOrOdd(state){
		return state.user.count%2==0?'偶数':'奇数';
	}
}

export default getters;

  

types.js

/**
 * 定义类型常量
 */

const INCREMENT='INCREMENT'
const DECREMENT='DECREMENT'

export default {
	INCREMENT,
	DECREMENT
}

  

index.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex);

import getters from './getters.js'
import actions from './actions.js'
import user from './modules/user.js'

export default new Vuex.Store({
	getters,
	actions,
	modules:{
		user
	}
});

  

main.js

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

import store from './store/index.js'

new Vue({
  store,
  el: '#app',
  render: h => h(App)
})

 

分模块组织的访问

        console.log(this.$store);
        console.log(this.$store.getters['dirTestcaseData']);
        console.log(this.$store.getters['user/count']);

        console.log(this.$store.state['project']);
        console.log(this.$store.state.user['count']);

        this.$store.dispatch("asset/changeCurrentFundIndex", index);
        this.$store.dispatch('increment');


//导入
import { mapState, mapGetters } from "vuex";

//批量引入
    ...mapGetters("asset", {
      assetDetailType: "assetDetailType",
      tradeSelectVal: "tradeSelectVal",
      totalAsset: "totalAsset"
    })  //也支持数组

 

posted @ 2018-07-25 14:02  财经知识狂魔  阅读(191)  评论(0编辑  收藏  举报