Vuex学习

480 阅读2分钟

一、什么是Vuex

官方:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。 个人理解:Vuex是管理应用程序的全局数据状态,这样任意组件都可以进行操作、修改、获取全局数据。

二、创建vuexdemo项目实例

vue/cli3.x命令:vue create vuexdemo

安装vuex命令:npm install --save-dev vuex

项目结构图:

三、创建store状态

1)在src下创建store文件夹,并且创建index.js文件

// store/index.js

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

Vue.use(Vuex);

const state = {
	name:"Vuex",
}

const store = new Vuex.Store({
	state:state
})

export default store

2)Vue使用store

//main.js

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

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

Vue.config.productionTip = false

new Vue({
	store,//Vue实例使用store(全局使用)
  render: h => h(App),
}).$mount('#app')

3)在HelloWorld.vue中获取store的state

<!-- HelloWorld -->

<template>
  <div class="hello">
    <h1>{{ this.$store.state.name }}</h1>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld'
}
</script>

<style scoped>
</style>

这时页面出现Vuex的字样

四、使用Getters获取状态

getter相当于Vue的computed的属性,用来监测变量的变化,监测state的最新状态,getters也是属于Store下的一部分(可以使用console.log(this.$store)打印出来观察store已有的属性及方法)。

// store/index.js

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

Vue.use(Vuex);

const state = {
	name:"Vuex",
	age:25
}

const getters = {
	getName(state){
		return state.name;
	},
	getAge(state){
		return state.age;
	}
}

const store = new Vuex.Store({
	state,
	getters
})

export default store

在HelloWorld.vue获取getters

<!-- HelloWorld -->

<template>
  <div class="hello">
    <h1>{{ this.$store.getters.getAge }}</h1>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld'
}
</script>

<style scoped>
</style>

这时页面显示一个25。

五、使用mutations(同步)

mutations是用来修改state里面的值,既然是修改值,修改的方法当然需要传入修改的参数值。

// store/index.js

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

Vue.use(Vuex);

const state = {
	name: "Vuex",
	age: 25
}

const getters = {
	getName(state) {
		return state.name;
	},
	getAge(state) {
		return state.age;
	}
}

const mutations = {
	setAge(state){
		state.age = 26;
		console.log("添加date",state.date);
		console.log("修改age",state.age);
	},
	setDate(state,date){
		state.date = date;
	}
}

const store = new Vuex.Store({
	state,
	getters,
	mutations
})

export default store


HelloWorld.vue

<!-- HelloWorld -->

<template>
  <div class="hello">
    <h1>{{ this.$store.getters.getAge }}</h1>
		<button @click="$store.commit('setDate','2019')">添加Date</button>
		<button @click="$store.commit('setAge')">修改age</button>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld'
}
</script>

<style scoped>
</style>

使用$store.commit('funcName',option)修改store的值,其中参数funcName为修改store的状态值的函数名,option为函数名的参数(非state)。

这时连续点击两个按钮,浏览器控制台打印出添加date 2019修改age 26。由于mutations里面只能是同步,不能进行异步操作,类似ajax请求的就不能放置于mutations里面。所以为了解决这个问题actions就出现了,action是可以进行任意的异步操作,其实action也是操作mutation的。只有mutation才能改变state的状态值。

六、使用actions(异步)

// store/index.js

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

Vue.use(Vuex);

const state = {
	name: "Vuex",
	age: 25
}

const getters = {
	getName(state) {
		return state.name;
	},
	getAge(state) {
		return state.age;
	}
}

const mutations = {
	setAge(state){
		state.age++;
		console.log("添加date",state.date);
		console.log("修改age",state.age);
	},
	setDate(state,date){
		state.date = date;
	}
}

const actions = {
	actionSetAge(comtext){
		comtext.commit('setAge');
	}
}

const store = new Vuex.Store({
	state,
	getters,
	mutations,
	actions
})

export default store

HelloWorld.vue

<!-- HelloWorld -->

<template>
  <div class="hello">
    <h1>{{ this.$store.getters.getAge }}</h1>
		<button @click="$store.commit('setDate','2019')">添加Date</button>
		<button @click="$store.dispatch('actionSetAge')">修改age</button>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld'
}
</script>

<style scoped>
</style>

这时点击修改age按钮就可以实时改变大数字了。 在HelloWorld.vue中我们可以看到$store.dispatch('func',option),参数与commit的参数一样的。其中actions下的方法也是执行mutation中的方法,比如comtext.commit('setAge');中的setAge就是mutation下的方法。

七、使用modules

1)store下创建modules文件夹,并且创建mod1.js和mod2.js文件。 mod1.js

//mod1.js

const state = {
	name: "mod1.js"
};

const getters = {
	getMod1Name:function(state){
		return state.name;
	}
}

export default {
	namespaced: true, //namespaced:true 表示当你需要在别的文件里面使用( mapGetters、mapActions 接下来会说 )时,里面的方法需要注明来自哪一个模块的方法
	state,
	getters
}

mod2.js

//mod2.js

const state = {
	name:"mod2.js"
};

const getters = {
	getMod2Name:function(state){
		return state.name;
	}
}

export default {
	namespaced: true, //namespaced:true 表示当你需要在别的文件里面使用( mapGetters、mapActions 接下来会说 )时,里面的方法需要注明来自哪一个模块的方法
	state,
	getters
}

index.js

// store/index.js

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

//引入模块
import mod1 from "./modules/mod1.js";
import mod2 from "./modules/mod2.js";

Vue.use(Vuex);

const state = {
	name: "Vuex",
	age: 25
}

const getters = {
	getName(state) {
		return state.name;
	},
	getAge(state) {
		return state.age;
	}
}

const mutations = {
	setAge(state){
		state.age++;
		console.log("添加date",state.date);
		console.log("修改age",state.age);
	},
	setDate(state,date){
		state.date = date;
	}
}

const actions = {
	actionSetAge(comtext){
		comtext.commit('setAge');
	}
}

const modules = {
	mod1,
	mod2
}

const store = new Vuex.Store({
	state,
	getters,
	mutations,
	actions,
	modules
})

export default store

HelloWorld.vue

<!-- HelloWorld -->

<template>
  <div class="hello">
    <h1>{{ this.$store.getters.getAge }}</h1>
		<button @click="$store.commit('setDate','2019')">添加Date</button>
		<button @click="$store.commit('setAge')">修改age</button>
		<p>{{this.$store.getters['mod1/getMod1Name']}}</p>
		<p>{{this.$store.getters['mod2/getMod2Name']}}</p>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld'
}
</script>

<style scoped>
</style>

浏览器显示

modules的作用是将过多的数据分隔开,让数据更加好管理。

八、使用mapGetters()等函数

mapGetters(option)就是this.$store.getters的写法,只是option参数是对应getters定义的行函数。

HelloWorld.vue

<!-- HelloWorld -->

<template>
	<div class="hello">
		<h1>{{ this.$store.getters.getAge }}</h1>
		<button @click="$store.commit('setDate', '2019')">添加Date</button>
		<button @click="$store.commit('setAge')">修改age</button>
		<p>{{ getMod1Name() }}</p>
		<p>{{ getMod2Name() }}</p>
	</div>
</template>

<script>
import { mapGetters } from 'vuex';

export default {
	name: 'HelloWorld',
	methods: {
		...mapGetters({
			getMod1Name: 'mod1/getMod1Name',
			getMod2Name: 'mod2/getMod2Name'
		})
	}
};
</script>

<style scoped></style>

页面同样可以显示

mod1.js

mod2.js

总结

这一片就是vuex的入门,还有很多vuex的知识还未涉及。若有不明白和不足的地方,可以留言一起探究。

摘要

VueJS中学习使用Vuex详解