1. vuex
vue中有父子组件之间的通信,但某些变量需要在全局使用,那就用到了vuex,Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。
2. 在vue3中的使用
创建一个vue3项目,具体如下vue-cli3的创建
记得在选配置的时候选上vuex
项目创建成功后,得到的项目目录如下
其中的store.js就是用来设置vuex的,查看store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
},
mutations: {
},
actions: {
}
})
- state 用来存放变量,也可在此初始化变量
- mutations 用来操作变量,更改 Vuex 的 store 中的状态的唯一方法是提交 mutation
- action Action 提交的是 mutation,而不是直接变更状态。Action 可以包含任意异步操作。
比如我想共享的状态有:开始时间,结束时间,时间类型,部门选择,类型,更改如下
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
startTime: new Date().getTime(),
endTime: new Date().getTime()+24*60*60*1000,
timeType: 'weekly',
departSelected: {
value: null, //
text: null
},
type: 1
},
mutations: {
setStartTime: function (state, n) {
state.startTime = n
},
setEndTime: function (state, n) {
state.endTime = n
},
setDepartSelected: function (state, n) {
state.departSelected = n
},
setTimeType: function (state, n) {
state.timeType = n
},
setType: function (state, n) {
state.type = n
}
},
actions: {
}
})
3. 获取和更改(简单使用)
3.1 获取
为了了解store,可以在页面的mounted中它打印出来,console.log(this.$store),结果如下
可以看到最后的state里面是变量,如果想获取
在js中
computed: {
timeType () {
return tthis.$store.state.timeType,
}
}
在template中使用去掉this即可
3.2 更改
更改要用到在mutations定义的方法,比如想更改timeType
this.$store.commit('setTimeType', 'monthly')
4. 更多应用
4.1 getter
有时候我们需要从 store 中的 state 中派生出一些状态,为了避免在其他组件代码中重复写,在store.js里的getter写即可,比如我想把state里的开始时间和结束时间拼接起来
Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算
在store.js中添加
getters: {
totalTime (state) {
return '开始时间:' + state.startTime + '结束时间:' + state.endTime
}
}
在页面mounted里打印出来
mounted () {
console.log(this.$store.getters.totalTime)
}
得到结果
getter就类似于组件里的computed,避免重新计算,有缓存,只要以来不变就不会重新计算
4.2 mapGetters 辅助函数
mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性:
import { mapGetters } from 'vuex'
export default {
name: 'home',
components: {
HelloWorld
},
mounted () {
console.log(this.totalTime)
},
computed: {
...mapGetters([
'totalTime'
// ...
])
}
}
就可以直接使用了
4.3 mapStatus辅助函数
用处和mapGetters类似,不过映射的是status里的内容,可以在页面中如下使用, store里的值就可以直接用了,不需要computed了
import { mapState } from 'vuex'
export default {
name: 'home',
mounted () {
console.log(this.startTime, this.endTime)
},
computed: {
...mapState([
'startTime', 'endTime'
])
}
}
4.4 action
Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters。
比如在store里加action,用来给startTime和endTime自增一天
actions: {
incrementTime (context) {
context.commit('setStartTime', context.state.startTime + 24 * 60 * 60 * 1000)
context.commit('setEndTime', context.state.endTime + 24 * 60 * 60 * 1000)
}
},
在页面中使用
mounted () {
console.log(this.totalTime)
this.$store.dispatch('incrementTime')
console.log(this.totalTime)
},
结果如下
mutation 必须同步执行,Action 就不受约束,可以在 action 内部执行异步操作
比如可以在action里写从后台获取数据的操作,或者定时器操作,以定时器操作为例(在项目中用的比较多的还是axios操作)
在store.js的action里增加
actions: {
incrementTime (context) {
context.commit('setStartTime', context.state.startTime + 24 * 60 * 60 * 1000)
context.commit('setEndTime', context.state.endTime + 24 * 60 * 60 * 1000)
},
incrementTimeAsync (context) {
setTimeout(() => {
context.commit('setStartTime', context.state.startTime + 24 * 60 * 60 * 1000)
context.commit('setEndTime', context.state.endTime + 24 * 60 * 60 * 1000)
}, 5000)
}
},
在页面中写
<template lang="pug">
div.home
div.test-part {{totalTime}}
</template>
<script>
// @ is an alias to /src
import { mapGetters } from 'vuex'
export default {
name: 'home',
mounted () {
this.$store.dispatch('incrementTimeAsync')
},
computed: {
...mapGetters([
'totalTime'
// ...
])
}
}
</script>
<style lang="scss">
.home {
.test-part{
height: 43px;
width: 100px;
}
}
可以看到效果如下
在5s后,数字增加