vuex - voa
页面需要多个共享的状态
缓存部分异步数据,减少后端服务的访问
state
中的值被存放在内存中,刷新页面则释放内存
一、提交mutation
必须通过commit
调用mutation
中的方法,来修改state
中的值,若不通过mutation
直接修改,则无法监听该过程。Vuex
中所有的状态更新的唯一途径都是mutation
,异步操作通过 Action
来提交 mutation
实现,这样使得我们可以方便地跟踪每一个状态的变化。
// changeCinemaList 为 mutation 内的方法名,payload 为入参
// 页面
this.$store.commit("changeCinemaList", payload)
// store.js
mutations: {
changeCinemaList(state,payload){
state.cinemaList = payload
}
}
二、提交action
用dispatch
调用action
中的方法后,也必须通过commit
调用mutation
中的方法,来修改state
中的值,若不通过mutation
直接修改,则无法监听该过程。
// getCinemaList 为 action 内的方法名,payload 为入参
//页面
this.$store.dispatch("getCinemaList", payload)
// store.js
actions: {
async getCinemaList(store, payload) {
var res = await axios({"https://m.maizuo.com/gateway?cityId=110100&ticketFlag=1&k=5385023"})
//提交mutation
store.commit("changeCinemaList",res.data.data.cinemas)
}
}
三、计算属性getters
相当于把computed
放在了store
中,通过this.$store.getters.filterCinemaList(type)
在页面上展示。
// store.js
getters:{
// state为当前整个状态数据,type为传参
// getters中返回的是一个函数
filterCinemaList: (state) => (type)=>{
return state.cinemaList.filter(item => item.eTicketFlag === type)
}
// else 若不用传参,则不需要用箭头函数
filterCinemaList(state){
(type)=>{
return state.cinemaList.filter(item => item.eTicketFlag === type)
}
}
}
四、辅助函数(切割函数)
-
切割
computed
将
store
中state
的属性映射出来,当做本地的属性,在computed
中插入了一个方法// 原型 computed: { inTabberShow() { return this.$store.state.inTabberShow } } // 可以返回多个 // mapState自身携带返回值,所以只需要传state中的属性名inTabberShow即可 computed: { // 通过this.inTabberShow调用,不用通过this.$store.state.inTabberShow访问 ...mapState(['inTabberShow']), // 继续写另一个方法 aaa() {} }
-
切割
mutation
将
store
中mutation
的方法映射出来,当做本地的方法,相当于在methods
中插入了一个方法// 可以返回多个 methods: { // 直接通过this.changeCinemaList()调用,不用通过this.$store.commit('changeCinemaList')提交至mutatio ...mapMutations(['changeCinemaList']), // 继续写另一个方法 aaa() {} }
-
切割
action
将
store
中action
的方法映射出来,当做本地的方法,相当于在methods
中插入了一个方法// 可以返回多个 methods: { // 直接通过this.getCinemaList(payload)调用,不用通过this.$store.dispatch("getCinemaList", payload)提交至action ...maoActions(['getCinemaList']), // 继续写另一个方法 aaa() {} }
-
切割
getters
将
store
中getters
的属性映射出来,当做本地的属性,在computed
中插入了一个方法// 可以返回多个 // mapGetters自身携带返回值,所以只需要传getters中的方法名filterCinemaList即可 computed: { // 通过this.filterCinemaList(type)调用,不用通过this.$store.getters.filterCinemaList(type)访问 // getters中返回的是一个函数 ...mapGetters(['filterCinemaList']), // 继续写另一个方法 aaa() {} }
五、模块化(Module)
vuex
允许将store
分割成模块module
,每个模块拥有自己的state
,mutation
,action
,getter
const moduleA = {
namespaced: true, // 开启命名空间
state: () => ({ ... }),
mutations: { ... },
action: { ... },
getters: { ... }
}
const moduleB = {
namespaced: true, // 开启命名空间
state: () => ({ ... }),
mutations: { ... },
action: { ... },
getters: { ... }
}
const store = createStore({
modules: {
moduleA,
moduleB
}
})
// 要拿moduleA中state里的属性
this.$store.state.moduleA.xxx // moduleA 的状态
// 要拿moduleA中getters里的属性
this.$store.getters.moduleB.xxx // moduleB 的状态
// 必须要先开启命名空间
computed: {
// 一位参数是module的名字,二参数为该module中的属性
...mapState('moduleA', ['isTabberShow']),
// 一位参数是module的名字,二参数为该module中的属性
...mapGetters('moduleA', ['filterCinemaList']),
// 继续写另一个方法
aaa() {}
}
// 必须要先开启命名空间
methods: {
// 一位参数是module的名字,二参数为该module中的属性
...mapMutations('moduleA', ['changeCinemaList']),
// 一位参数是module的名字,二参数为该module中的属性
...maoActions('moduleA',['getCinemaList']),
// 继续写另一个方法
aaa() {}
}
vuex - vca
import { useStore } from 'vuex'
const store = useStore()
onBeforeMount(() => {
// 在moduleA中开启命名空间后,提交mutation
store.commit('moduleA/changeCinemaList', payload)
// 在moduleA中开启命名空间后,使用action方法
store.dispatch("moduleA/getCinemaList", payload)
})
// template中getters的写法
<div v-for="item in store.getters['moduleA/filterCinemaList'](type)" :key="item.id">
{{item}}
</div>
vca
不支持辅助函数,辅助函数的源码中带了this
import { useStore } from 'vuex'
const store = useStore()
const state = mapState("moduleA", ["isTabberShow"])
// 但可以通过bind重新绑定,改变this指向并返回一个修正this指向的新函数
// 将$store指向store
state.isTabberShow = state.isTabberShow.bind({$store: store})
const isTabberShow = computed(state.isTabberShow)
vuex-持久化
将数据持久化至sessionStorage
、localStorage
、cookie
中
安装
npm i vuex-persistedstate --save
用法
import { createStore } from 'vuex'
import createPersistedState from 'vuex-persistedstate'
const store = createStore({
modules: {
moduleA,
moduleB
},
plugins: [createPersistedState({
reducer: (state) => {
return {
isTabberShow: state.moduleA.isTabberShow
}
}
})]
})