一、简介
Vuex 是一个专为 Vue 开发的应用程序的状态管理模式,它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
包含模块
· State:定义了应用状态的数据结构,可以在这里设置默认的初始状态。
· Getter:允许组件从 store 中获取数据,mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性。
· Mutation:是唯一更改 store 中状态的方法,且必须是同步函数。
· Action:用于提交 mutation,而不是直接变更状态,可以包含任意异步操作。
· Module:可以将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、 action、getter、甚至是嵌套子模块
二、使用
1、在store文件夹,新建个index.js文件
import Vue from "vue"
import Vuex from "vuex"
Vue.use(Vuex);
export default new Vuex.Store({
state:{
pathName: "",
currDbSource: {},
currJobData: {},
DbSource: []
},
mutations:{
// 保存当前菜单栏的路径
savePath(state,pathName){
state.pathName = pathName;
},
// 保存当前点击的数据源
saveCurrDbSource(state,currDbSource){
state.currDbSource = currDbSource;
},
// 保存当前点击的元数据
saveCurrJobData(state,currJobData){
state.currJobData = currJobData;
},
// 保存所有数据源
saveDbSource(state,DbSource){
state.DbSource = DbSource;
}
}
})
2、main.js引用:(注意路径即可)
// 引入vuex-store
import store from './store/index';
new Vue({
el: '#app',
router,
store,
render: h => h(App)
});
3、保存数据:(场景举例:当我点击按钮后,我需要把当前的数据保存到vuex中,然后跳转到别的路由,然后使用这些数据)
methods:{
click(){
// 点击按钮进行一些操作,然后保存数据
this.$store.commit('saveCurrDbSource',this.db)
}
}
4、获取变量:(当数据初始获取不到时,可以使用计算属性用来获取)
this.$store.state.变量名
// 例如
this.$store.state.currDbSource
三、模块的使用
1. State
假设我们有一个全局状态 count
的值为 5。那么,我们就可以将其定义为 state
对象中的 key
和 value
,作为全局状态供我们使用。如下:
//创建一个 store
const store = new Vuex.Store({
//state存储应用层的状态
state:{
count:5 //总数:5
}
});
2. Getters
getters
是store的计算属性,类似于computed
,对state里的数据进行一些过滤,改造等等
假设我们要在state.count
的基础上派生出一个新的状态newCount
出来,就适合使用我们的 getters
getters
接受 state
作为其第一个参数
const store = new Vuex.Store({
//state存储应用层的状态
state:{
count:5 //总数:5
},
getters:{
newCount:state => state.count * 3
}
});
在组件中获取 {{newCount}}
方式:
export default {
computed: {
newCount(){
return this.$store.getters.newCount;
}
}
};
3. Mutations
Vuex
给我们提供修改仓库store
中的状态的唯一办法就是通过提交mutation
,且必须是同步函数
我们在 mutations
中定义了一个叫increment
的函数,函数体就是我们要进行更改的地方
会接受 state
作为第一个参数,第二个是自定义传参
const store = new Vuex.Store({
//state存储应用层的状态
state:{
count:5 //总数:5
},
// mutations是修改state中数据的唯一途径
mutations:{
increment(state,value){
state.count += value;
}
}
});
我们在提交commit
时候,第一个参数"increment"
,就是对应在 mutations
中的increment
方法,第二个参数是自定义值。例如:
methods: {
getVal(event) {
//获取当前的按键的值
let value = event.target.dataset.value;
//通过commit提交一个名为increment的mutation
this.$store.commit("increment", value);
}
}
在组件中获取 {{count}}
方式:
export default {
computed: {
count(){
return this.$store.state.count;
}
}
};
4. Action
- 用于提交
mutation
,而不是直接变更状态,可以包含任意异步操作- 只有通过
action=>mutations=>states
,这个流程进行操作
具体步骤如下:
export default new Vuex.Store({
//存放数据
state: {
obj: {},
},
//4. 通过commit mutations中的方法来处理
mutations: {
getParam(state, Object) {
//5.修改state中的数据
state.obj = Object
}
},
//2.接受dispatch传递过来的方法和参数
actions: {
getParamSync(store, Object) {
// 处理异步操作
setTimeout(() => {
//3.通过commit提交一个名为getParam的mutation
//action 函数接收一个 store 的实例对象,因此你可以调用 store.commit 提交一个 mutation
store.commit('getParam', Object);
}, 1000)
}
}
})
然后我们就在组件里这么调用就可以了
methods: {
getVal() {
let name= 'xia';
let age= '26';
let sex= 'man';
//1.通过dispatch将方法getParamSync和多个参数{name,age,sex}传递给actions
this.$store.dispatch('getParamSync',{name,age,sex})
}
}
5. Modules
随着项目的复杂度增大,为了方便管理 Vuex,一般会将其按功能分割成不同的模块(
Module
),方便日后管理。每个模块拥有自己的state
、mutation
、action
、getter
甚至是嵌套子模块
import Vue from 'vue'
import Vuex from 'vuex'
import state from './state'
import mutations from './mutations'
import actions from './actions'
import * as getters from './getters'
import moduleA from './module/moduleA' // 模块A
import moduleB from './module/moduleB' // 模块B
Vue.use(Vuex)
export default new Vuex.Store({
actions,
getters,
state,
mutations,
modules: {
moduleA,
moduleB
}
})
moduleA.js
/ moduleB.js
文件
// 每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块
export default {
state: {
text: 'moduleA'
},
getters: {},
mutations: {},
actions: {}
}
然后我们就在组件里这么调用就可以了
<template>
<div class="demo">
<h1>{{getText1}}</h1>
<h1>{{getText2}}</h1>
</div>
</template>
computed: {
getText1(){
return this.$store.state.moduleA.text;
},
//或
...mapState({
getText2: state => state.moduleB.text;
})
}