Vuex是什么
Vuex是一个为了管理共享状态的工具,是一个全局模型,在开发大型单页面应用过程中作用大,如果不是大型单页面开发,那 Vuex 可能还是你的一个负担。
一个例子
new Vue({
// state 数据源
data () {
return {
count: 0
}
},
// view 视图
template: `
<div>{{ count }}</div>
`,
// actions 事件
methods: {
increment () {
this.count++
}
}
})
这是一个很简单的增长型计数功能页面,通过事件increment,实现count增长,然后渲染到界面上去。
这种方式官方称作为 单项数据流,这种方式用Vuex反而是一种负担。
现在有两个页面A和B,有以下两个要求:
- 要求他们都能对count进行操控。
- 要求A修改了count后,B要第一时间知道,B修改后,A也要第一时间知道。
很容易想到的实现方式:把数据源count剥离开来,用一个全局变量或者全局单例的模式进行管理,这样不就在任何页面都可以很容易的取到这个状态了。
这就是Vuex背后的思想,全局模型。
Vuex的目的是为了管理共享状态,为了达到这个目的,它制定了一系列的规则,比如修改数据源 state、触发 actions 等等,都需要遵循它的规则,以此来达到让项目结构更加清晰且易于维护的目的。
官方描述:
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
Vuex的一个示例
// 如果在模块化构建系统中,请确保在开头调用了 Vue.use(Vuex)
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
}
})
//mutations 可以单纯的理解为只能用它里面的方法来修改 state 中的数据。
store.commit('increment') // 调用 mutations 中的方法
console.log(store.state.count) // -> 1
每一个 Vuex 应用的核心就是 store(仓库)。store 基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。
store模式
store模式是一个单纯的全局对象,适用于一些不大不小的项目。
Vuex与全局对象之间的区别:
Vuex与单纯的全局对象有以下两点不同:
- Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
- 你不能直接改变 store 中的状态。改变 store 中状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。
//Vue文件中
<template>
<div class="containerBox">
<div class="closeData">数据更新至:{{closeDate.closeDate}}</div>
<span @click="goToPage(item.path)">返回</span>
<p>{{$store.getters.quadratic}}</p>//页面显示10000
</div>
</template>
<script>
import {mapState, mapGetters, mapActions} from 'vuex';
//mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性:
export default {
name: "DailyWork",
data: function() {
return {
};
},
props: {
},
computed: {
...mapState("masterInfo", ['closeDate']),//获取masterInfo返回的close 只能获取 不能修改
...mapGetters('masterInfo', ['dateInfo']),//修改masterInfo返回的dateInfo mapGetters里面的都是store.js里面的getters的方法名
},
components: {
},
watch: {
semesterItem: function(newValue, oldValue) {
if (newValue.key !== oldValue.key) {
let vm = this;
vm.$store.commit("masterInfo/setDateInfo", {
date: vm.semesterItem.key,
dateCh: vm.semesterItem.value,
dtFlag: vm.choiceTimeInfo.value,
dtFlagCh: vm.choiceTimeInfo.name
});
}
},
},
methods: {
...mapActions(['getUserInfo']),
goToPage(path) {
this.getUserInfo().then((result) => {//老师角色跳教研员首页矫正
const {success, userInfo={}} = result;
if (success) {
if (userInfo.userType === "TEACHER" && path ==='/restaff') {
path = '/teacher/teacherofcourse';
}
}
this.$router.push(path);
});
}
},
created() {
},
mounted: async function() {
}
};
</script>
store下index.js
import Vue from 'vueEsm';
import Vuex from 'vuex';
import masterInfo from './module/masterInfo';
import {
userInfo
} from '@/api/user';
Vue.use(Vuex);//如果在模块化构建系统中,请确保在开头调用了 Vue.use(Vuex)
export default new Vuex.Store({
//创建一个对象来保存应用启动时的初始状态 类似于组件中的data 存放数据
state: {
userInfoRequest: false,
count: 100,
userinfo:[
{userId:1,name:"开发者-1",age:"20"},
{userId:2,name:"开发者-2",age:"18"},
{userId:3,name:"开发者-3",age:"28"},
{userId:4,name:"开发者-4",age:"36"},
{userId:5,name:"开发者-5",age:"12"}
]
},
//getters,可以认为是store的计算属性,就是在某个数据在经过一系列的变化之后,才显示在页面上,这个时候就需要用到计算属性。
getters: {
userInfo: state => {
return state.teacher.userInfo || state.restaff.userInfo;
},
quadratic(state){
//state.counter平方
return state.counter * state.counter
},
//筛选state.userinfo中age大于18的数据
filteruser(state){
return state.userinfo.filter(res => {
return res.age > 18
})
}
},
//mutations 可以单纯的理解为只能用它里面的方法来修改 state 中的数据。类似于组件中的methods
mutations: {
},
//提交mutations
actions: {
getUserInfo({state, commit, dispatch}, payload) {
if (!state.userInfoRequest) {
const _$userInfo = state.teacher.userInfo || state.restaff.userInfo;
if (_$userInfo) {
return _$userInfo;
} else {
return state.userInfoRequest = userInfo().then((result) => {
const {success, userInfo} = result;
if (success) {
if (userInfo?.userType === 0) {
state.restaff.userInfo = result;
} else if (userInfo?.userType === "TEACHER") {
state.teacher.userInfo = result;
}
}
return result;
});
}
} else {
return state.teacher.userInfo || state.restaff.userInfo || state.userInfoRequest;
}
}
},
//把以上四个属性再细分,让仓库更好管理
modules: {
masterInfo
}
});
store 下module下masterInfo.js
/*获取区域管理者 校长接口需要的参数*/
export default {
namespaced: true,
state: {
dateInfo: {
date: '',
dateCh: '',
dtFlag: '',
dtFlagCh: '',
weekValue: ''
}, //区域管理者接口需要的参数
schoolDateInfo: {
date: '',
dateCh: '',
dtFlag: '',
dtFlagCh: '',
weekValue: ''
}, //校长接口需要的参数
closeDate: "",
periodInfo: {
name: '',
value: '',
schoolLevel: ''
}
},
getters: {
},
mutations: {
setDateInfo(state, payload) {
state.dateInfo = payload;
},
setSchoolDateInfo(state, payload) {
state.schoolDateInfo = payload;
},
getCloseDate(state, payload) {
state.closeDate = payload;
},
getPeriodInfo(state, payload) {
state.periodInfo = payload;
},
},
actions: {
}
};