通过 vuex action 自动设置 loading state. 免去每次请求时都需要手动修改 loading state 的麻烦. 灵感来源于 dva-loading.
$ npm install vuex-plugin-loading or yarn add vuex-plugin-loading
import createVuexLoadingPlugin from "vuex-plugin-loading";
new Vuex.Store({
...
plugins: [createVuexLoadingPlugin()]
});
随后你就可以通过 store 使用对应的 loading state
opts.namespace
: 该属性表示 loading 模块的命名空间. 类型为 String. 默认值为loadingStore
opts.rootNamespace
: 该属性表示跟模块的命名空间. 类型为 String. 默认值为rootStore
loadingStore: {
global: false,
models: {
users: false,
...
},
actions: {
users/login: false,
users/logout: false,
...
}
}
<template>
<div>
<LeftComponent :data="leftData" v-loading="loadingByLeft" />
<RightComponent :data="rightData" v-loading="loadingByRight" />
</div>
</template>
<script>
import { createNamespacedHelpers } from 'vuex'
import LeftComponent from '@/components/LeftComponent'
import RightComponent from '@/components/RightComponent'
const { mapState, mapActions } = createNamespacedHelpers('testStore')
const { mapState: mapStateByLoadingStore } = createNamespacedHelpers('loadingStore')
export default {
name: 'TestComponent',
components: { LeftComponent, RightComponent },
computed: {
...mapState(['leftData', 'rightData']),
...mapStateByLoadingStore({
loadingByLeft({ actions }) {
return actions['testStore/getLeftData']
},
loadingByRight({ actions }) {
return actions['testStore/getRightData']
},
}),
},
methods: {
...mapActions(['getLeftData', 'getRightData']),
},
mounted() {
this.getLeftData()
this.getRightData()
},
}
</script>
const state = {
leftData: [],
rightData: [],
}
const mutations = {
setState(state, payload) {
Object.assign(state, payload)
},
}
const actions = {
async getLeftData({ commit }) {
const res = await get('对应的请求路径')
commit('setState', { leftData: res.data })
return res
},
async getRightData({ commit }) {
const res = await get('对应的请求路径')
commit('setState', { rightData: res.data })
return res
},
}
export const testStore = {
namespaced: true, // 一定记得开启命名空间
state,
actions,
mutations,
}
...
...
import { testStore } from '@/pages/Test/store'
new Vuex.Store({
...
modules: {
testStore, // 这里的命名将作为对应 loading 的命名空间前缀
},
})
<template>
<div v-loading="loading">
<LeftComponent :data="leftData" />
<RightComponent :data="rightData" />
</div>
</template>
<script>
import { createNamespacedHelpers } from 'vuex'
import LeftComponent from '@/components/LeftComponent'
import RightComponent from '@/components/RightComponent'
const { mapState, mapActions } = createNamespacedHelpers('testStore')
const { mapState: mapStateByLoadingStore } = createNamespacedHelpers('loadingStore')
export default {
name: 'TestComponent',
components: { LeftComponent, RightComponent },
computed: {
...mapState(['leftData', 'rightData']),
...mapStateByLoadingStore({
loading({ modules }) {
return modules['testStore']
},
}),
},
methods: {
...mapActions(['getLeftData', 'getRightData']),
},
mounted() {
this.getLeftData()
this.getRightData()
},
}
</script>
const state = {
leftData: [],
rightData: [],
}
const mutations = {
setState(state, payload) {
Object.assign(state, payload)
},
}
const actions = {
async getLeftData({ commit }) {
const res = await get('对应的请求路径')
commit('setState', { leftData: res.data })
return res
},
async getRightData({ commit }) {
const res = await get('对应的请求路径')
commit('setState', { rightData: res.data })
return res
},
}
export const testStore = {
namespaced: true, // 一定记得开启命名空间
state,
actions,
mutations,
}
...
...
import { testStore } from '@/pages/Test/store'
new Vuex.Store({
...
modules: {
testStore, // 这里的命名将作为对应 loading 的命名空间前缀
},
})
<template>
<div v-loading="loading">
<LeftComponent :data="leftData" />
<RightComponent :data="rightData" />
</div>
</template>
<script>
import { createNamespacedHelpers } from 'vuex'
import LeftComponent from '@/components/LeftComponent'
import RightComponent from '@/components/RightComponent'
const { mapState, mapActions } = createNamespacedHelpers('testStore')
const { mapState: mapStateByLoadingStore } = createNamespacedHelpers('loadingStore')
export default {
name: 'TestComponent',
components: { LeftComponent, RightComponent },
computed: {
...mapState(['leftData', 'rightData']),
...mapStateByLoadingStore({
loading({ global }) {
return global
},
}),
},
methods: {
...mapActions(['getLeftData', 'getRightData']),
},
mounted() {
this.getLeftData()
this.getRightData()
},
}
</script>
const state = {
leftData: [],
rightData: [],
}
const mutations = {
setState(state, payload) {
Object.assign(state, payload)
},
}
const actions = {
async getLeftData({ commit }) {
const res = await get('对应的请求路径')
commit('setState', { leftData: res.data })
return res
},
async getRightData({ commit }) {
const res = await get('对应的请求路径')
commit('setState', { rightData: res.data })
return res
},
}
export const testStore = {
namespaced: true, // 一定记得开启命名空间
state,
actions,
mutations,
}
...
...
import { testStore } from '@/pages/Test/store'
new Vuex.Store({
...
modules: {
testStore, // 这里的命名将作为对应 loading 的命名空间前缀
},
})