一、什么是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的知识还未涉及。若有不明白和不足的地方,可以留言一起探究。