vuex的使用
2019-12-25 本文已影响0人
青争小台
1.模块化使用时
模块内:
//方法一:使用export default统一抛出
const user = {
state: {
admins_info: ''
},
mutations: {
SET_ADMINS(state, admins) {
state.admins_info = admins
}
},
actions: {
SET_ADMINS(context, admins) {
context.commit('SET_ADMINS', admins)
}
}
}
export default user
//方法二:使用export单个抛出
const state = {
admins: ''
}
const mutations = {
SET_ADMINS: (state, admins) => {
state.admins = admins
}
}
const actions = {
SET_ADMINS(context, admins) {
context.commit('SET_ADMINS', admins)
}
}
export default {
//成为一个带命名空间的模块
namespaced: true,
state,
mutations,
actions
}
getter,mutation,action 他们默认都是注册在全局命名空间的,所以我们默认是可以和使用根状态一样去使用他们,但是这样不可避免会出现命名冲突的问题,所以使模块有更高的封装性与复用性,我们可以通过添加
namespaced: true
使其成为带命名空间的模块。当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名。
页面使用:
import { auth } from '@/api/login'
import { mapState } from 'vuex'
export default {
name: 'Login',
data() {
return {}
},
methods: {
login(){
auth().then(response => {
//当使用方法一导出时
this.$store.dispatch('SET_ADMINS', response.data})
//当使用方法二导出时
this.$store.dispatch('user/SET_ADMINS', response.data})
})
}
},
computed: {
//当使用方法一导出时
...mapState({
admins_info: state => state.user.admins_info
})
//当使用方法二导出时,也可以用上面那个方法
...mapState('user', {
admins_info: state => state.admins_info
})
}
}
store 里
// import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'
import app from './modules/app'
import settings from './modules/settings'
import user from './modules/user'
// import createPersistedState from 'vuex-persistedstate' vuex的持久化存储
import VuexPersistence from 'vuex-persist' //vuex的持久化存储
// Vue.use(Vuex)
const vuexLocal = new VuexPersistence({
storage: window.localStorage
})
const store = new Vuex.Store({
modules: {
app,
settings,
user
},
getters,
plugins: [vuexLocal.plugin] //vuex的持久化存储
// plugins: [VuexPersistence()]----vuex的持久化存储
})
export default store
2.辅助函数
//当是将vuex模块化时,有三个模块app,user,setting,此时需要在state后加上模块名,action需要加上空间名
...mapState({
admins_info: state => state.user.admins_info.admins,
sidebar: state => state.app.sidebar,
device: state => state.app.device,
fixedHeader: state => state.settings.fixedHeader
})
...mapActions({'closeSideBar':'app/closeSideBar',SET_ADMINS:'user/SET_ADMINS'}),
this.closeSideBar({ withoutAnimation: false })//调用action
//当没有模块化时,直接state就行
...mapState({
add: state => state.add,
counts: state => state.counts
})
//当没有模块化时,并且赋值前后属性名一样时(...mapState,...mapGetters,...mapActions),可以简写成如下:
...mapState([
'add',
'counts'
])
...mapGetters(['filteredList'])
...mapActions(['closeSideBar']),
//...mapState,处理后的state数据
...mapState({
admins_info: state => state.user.admins_info.admins,
NO(state) {
return {no:state.user.admins_info.admins.no}
}
})
// getter
this.$store.getters['moduleB/bFullName'];
...mapGetters({
bGetter2: 'moduleB/bFullName'
})
// mutation
this.$store.commit('moduleB/SET_B_NAME', {
name: 'QQ'
});
...mapMutations({
setBname: 'moduleB/SET_B_NAME'
}),
// action
this.$store.dispatch('moduleB/ASYNC_SET_NAME', { name: "JJ" });
...mapActions({
aSetAge: 'moduleB/ASYNC_SET_NAME',
}),
每次都要写模块名,这样写下来很烦,所以这些辅助函数给我们提供了一个参数位来绑定命名空间。
// moduleB 模块内的 bName
...mapState('moduleB', {
name: state => state.bName
})
// 同理 mapAction mapMutation 也可以这个样子
...mapAction('moduleB',[
'/ASYNC_SET_NAME'
])
除了这个之外,如果你当前组件用的 vuex 状态都是一个模块的话,我们可以使用 createNamespacedHelpers 创建基于某个命名空间辅助函数,如下:
import { createNamespacedHelpers } from 'vuex'
const { mapState, mapActions } = createNamespacedHelpers('moduleB') // moduleName
这样创建之后,我们就可以用之前的写法来访问到模块的状态。
...mapState({
bName: state => state.bName,
}),
3.在带命名空间的模块内访问全局内容
如果你希望使用全局 state 和 getter,rootState 和 rootGetter 会作为第三和第四参数传入 getter,也会通过 context 对象的属性传入 action。
若需要在全局命名空间内分发 action 或提交 mutation,将 { root: true } 作为第三参数传给 dispatch 或 commit 即可。具体看下面代码:
modules: {
foo: {
namespaced: true,
getters: {
// 在这个模块的 getter 中,`getters` 被局部化了
// 你可以使用 getter 的第四个参数来调用 `rootGetters`
someGetter (state, getters, rootState, rootGetters) {
getters.someOtherGetter // -> 'foo/someOtherGetter 模块内的 getter'
rootGetters.someOtherGetter // -> 'someOtherGetter 全局的getter'
},
someOtherGetter: state => { ... }
},
actions: {
// 在这个模块中, dispatch 和 commit 也被局部化了
// 他们可以接受 `root` 属性以访问根 dispatch 或 commit
someAction ({ dispatch, commit, getters, rootGetters }) {
getters.someGetter // -> 'foo/someGetter'
rootGetters.someGetter // -> 'someGetter'
dispatch('someOtherAction') // -> 'foo/someOtherAction' 模块内的 action
dispatch('someOtherAction', null, { root: true }) // ->'someOtherAction' 全局的 action
commit('someMutation') // -> 'foo/someMutation' 模块内的 action
commit('someMutation', null, { root: true }) // -> 'someMutation' 全局 mutation
},
someOtherAction (ctx, payload) { ... }
}
}
}
4.将模块内的 action 注册为全局
这个感觉和维护模块的封装性有点冲突,但是既然作者提出来了,那就学吧,当我们想要我们模块内的某个 action 提升为全局 action 的时候,在他声明的时候,添加 root: true,并将 action 的定义放到 hanler 函数中,具体如下:
const actions = {
// 模块内 action
[ASET_AGE]({ commit }, payload) {
setTimeout(() => {
commit('SET_B_NAME', payload.name);
}, 2000)
},
// 提升到全局的 action
globalAction: {
root: true,
handler({ commit }, payload) {
debugger
setTimeout(() => {
commit('SET_B_NAME', payload.name);
}, 2000)
}
}
}