【sduoj】Vuex 全局状态管理

2021SC@SDUSC

前言

在上一次博客中,我们简单介绍了一下 Vuex 以及它的用法。在这一篇博客中,我们将实地分析 sduoj 项目中的 Vuex 的使用。

【sduoj】初识 Vuex

store.js

为了方便维护,我们为 Vuex 专门建立一个 js 文件,store.js ,将其至于 src 目录下。
在其内部,我们先将 VueVuex 引入:

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

接下来我们就可以编写具体的 store 了:

// 实例化一个 Vuex.Store 对象,并将其作为默认项导出
export default new Vuex.Store({
    
    
	state: {
    
    
		token: null, // 用户身份鉴权使用的JWT
		isTeacher: false,
		isAdmin: false,
		myInfo: {
    
    
			avatar: null,
			nickname: null,
            realName: null,
            stuNum: null,
            userId: undefined,
            username: null,
		},
		problemSetInfo: {
    
    
            problems: [],
            title: "",
            announcement: "",
            author: "",
            open: undefined,
            beginTime: "1970-01-01",
            endTime: "1970-01-01",
            status: 0,
            isMyProblemSet: false,
            problemIds: [],
            problemSetId: 0,
        }
	},
	mutations: {
    
    
        setToken(state, token) {
    
    
            state.token = token
        },
        setNoToken(state, noToken) {
    
    
            state.noToken = noToken;
        },
        setIsTeacher(state, isTeacher) {
    
    
            state.isTeacher = isTeacher;
        },
        setIsAdmin(state, isAdmin) {
    
    
            state.isAdmin = isAdmin;
            state.isTeacher = isAdmin;
        },
        setMyInfo(state, myInfo) {
    
    
            for (const key in myInfo) {
    
    
                Vue.set(state.myInfo, key, myInfo[key])
            }
        },
        setProblemSetInfo(state, newInfo) {
    
    
            for (const key in newInfo) {
    
    
                Vue.set(state.problemSetInfo, key, newInfo[key])
            }
        },
    },
    actions: {
    
    
        setToken(context, token) {
    
    
            context.commit('setToken', token);
        },
        setNoToken(context, noToken) {
    
    
            context.commit('setNoToken', noToken);
        },
        setIsTeacher(context, isTeacher) {
    
    
            context.commit('setIsTeacher', isTeacher);
        },
        setIsAdmin(context, isAdmin) {
    
    
            context.commit('setIsAdmin', isAdmin);
        },
        setMyInfo(context, myInfo) {
    
    
            context.commit('setMyInfo', myInfo);
        },
        setProblemSetInfo(context, newInfo) {
    
    
            context.commit('setProblemSetInfo', newInfo);
        },
    },
    getters: {
    
    
        usernameToShow: (state) => {
    
    
            return state.myInfo.nickname ? state.myInfo.nickname : (state.myInfo.realName ? state.myInfo.realName : state.myInfo.username)
        }
    },
})

引入项目

现在,我们已经有了一个可以使用的 store.js 了,我们还需要将它引入到该项目中才能正式使用。
在项目的 main.js 中:

/*
 * src/main.js
 */

import Vue from 'vue'
import App from './App.vue'
import store from './store';

new Vue({
    
    
    store,
    render: h => h(App)
}).$mount('#app')

Others

利用 Vuex 提高性能

sduoj 发送 http 请求时的鉴权方式是向服务器提供一个 JWT 的字符串,该字符串会在用户登录时使用 localStorage.setItem 存储在磁盘中,每当我们希望发送 http 请求时,就需要调用 localStorage.getItem 从磁盘中将 JWT 取出。显然,如果我们每次发送请求都需要从磁盘中读取 JWT ,虽然短期看来单次操作的开支似乎很小,但其效率必定是低下的。因此我们不妨在项目启动时或是用户登录时就将 JWT 从磁盘中取出,存放在 Vuex 中。这样我们每次发送请求就只需要从 Vuex 中读取需要的数据。访问内存的效率显然比反复读取磁盘数据的性能要高。

猜你喜欢

转载自blog.csdn.net/qq_53126706/article/details/121843204