vuex持久化

This commit is contained in:
2021-09-17 18:11:07 +08:00
parent c708459ff3
commit ffde8dbb92
7 changed files with 57 additions and 38 deletions

View File

@@ -12,7 +12,8 @@
"store": "^2.0.12",
"vue": "^3.2.11",
"vue-router": "^4.0.11",
"vuex": "^4.0.2"
"vuex": "^4.0.2",
"vuex-persistedstate": "^4.0.0"
},
"devDependencies": {
"@types/store": "^2.0.2",

View File

@@ -1,6 +1,5 @@
import { ACCESS_TOKEN } from '@/config'
import vuex from '@/store'
import type { MyRouteMeta, MyRouteRecordRaw } from '@/types/router'
import store from 'store'
import { createRouter, createWebHistory } from 'vue-router'
import auth from './routers/auth'
import user from './routers/user'
@@ -51,7 +50,7 @@ const router = createRouter({
router.beforeEach((to, from, next) => {
typeof to.meta !== 'undefined' && setDocumentTitle(<MyRouteMeta>to.meta)
const isAuthenticated: string = store.get(ACCESS_TOKEN)
const isAuthenticated: string = vuex.getters.isLogin
if (to.name !== 'AuthLogin' && to.meta.requiresAuth && !isAuthenticated) {
next({ name: 'AuthLogin', query: { to: to.path } })

View File

@@ -1,17 +1,16 @@
import { UserInfo } from '@/types/user'
import { LoginResponse } from '@/types/auth'
import { InjectionKey } from 'vue'
import { createStore, Store, useStore as baseUseStore } from 'vuex'
import createPersistedState from 'vuex-persistedstate'
import auth, { AuthState } from './modules/auth'
import refresh, { RefreshState } from './modules/refresh'
/**
* 这个KEY是为了针对 state 的类型提示来用的
*/
export const key: InjectionKey<Store<State>> = Symbol()
export interface State {
isLogin: boolean
userInfo: UserInfo
accessToken: string
tokenType: string
auth?: AuthState
refresh?: RefreshState
}
@@ -20,18 +19,38 @@ export default createStore<State>({
strict: true,
state: {
isLogin: false,
userInfo: {} as UserInfo
accessToken: '',
tokenType: ''
},
getters: {
isLogin: (state: State) => {
return state.isLogin
},
// 获取组合后的token
accessToken: (state: State) => {
return state.tokenType + ' ' + state.accessToken
}
},
mutations: {
setAccessToken (state: State, payload: LoginResponse) {
state.accessToken = payload.access_token
state.tokenType = payload.token_type
state.isLogin = true
},
cleanAccessToken (state: State) {
state.accessToken = ''
state.tokenType = ''
state.isLogin = false
}
},
getters: {},
mutations: {},
actions: {},
modules: {
auth,
refresh
}
},
plugins: [createPersistedState()]
})
// 导出函数,为了简化 useStore 的使用
// import { useStore } from '@/store'
export const useStore = (): Store<State> => {
return baseUseStore(key)

View File

@@ -1,35 +1,19 @@
import { auth } from '@/api'
import { State } from '@/store'
import { LoginData, LoginResponse } from '@/types/auth'
import { LoginData } from '@/types/auth'
import { Module } from 'vuex'
const initState = {
accessToken: '',
accessType: '',
isLogin: false
}
const initState = {}
export default {
strict: true,
namespaced: true,
state: initState,
mutations: {
login (state: AuthState, payload: LoginResponse) {
state.accessToken = payload.access_token
state.accessType = payload.token_type
state.isLogin = true
},
logout (state: AuthState) {
state.accessToken = ''
state.accessType = ''
state.isLogin = false
}
},
actions: {
Login: ({ commit }, payload: LoginData) => {
return new Promise((resolve, reject) => {
auth.login(payload).then(response => {
commit('login', response)
commit('setAccessToken', response, { root: true })
commit('refresh/setUser', true, { root: true })
resolve(response)
}).catch(error => {
@@ -37,10 +21,9 @@ export default {
})
})
},
// 登出
Logout ({ commit }) {
return new Promise((resolve) => {
commit('logout')
commit('cleanAccessToken', null, { root: true })
resolve(true)
})
}

View File

@@ -1,6 +1,5 @@
import { ACCESS_TOKEN } from '@/config'
import vuex from '@/store'
import axios, { AxiosRequestConfig } from 'axios'
import store from 'store'
import router from '../router'
const request = axios.create({
@@ -13,7 +12,7 @@ const request = axios.create({
* @param config
*/
const axiosConf = (config: AxiosRequestConfig) => {
config.headers.Authorization = store.get(ACCESS_TOKEN)
config.headers.Authorization = vuex.getters.accessToken
config.headers.Accept = 'application/json'
return config
}

View File

@@ -1,6 +1,7 @@
<template>
登录
<button @click="onLogin">一键登录</button>
<button @click="onLogout">退出登录</button>
</template>
<script lang="ts" setup>
@@ -15,6 +16,10 @@ const onLogin = () => {
console.error('error', err)
})
}
const onLogout = () => {
store.dispatch('auth/Logout')
}
</script>
<style scoped>

View File

@@ -7835,6 +7835,11 @@ shell-quote@^1.6.1:
resolved "https://registry.nlark.com/shell-quote/download/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2"
integrity sha1-Z6fQLHbJ2iT5nSCAj8re0ODgS+I=
shvl@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/shvl/-/shvl-2.0.3.tgz#eb4bd37644f5684bba1fc52c3010c96fb5e6afd1"
integrity sha512-V7C6S9Hlol6SzOJPnQ7qzOVEWUQImt3BNmmzh40wObhla3XOYMe4gGiYzLrJd5TFa+cI2f9LKIRJTTKZSTbWgw==
side-channel@^1.0.4:
version "1.0.4"
resolved "https://registry.nlark.com/side-channel/download/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf"
@@ -8906,6 +8911,14 @@ vue@^3.2.11:
"@vue/runtime-dom" "3.2.11"
"@vue/shared" "3.2.11"
vuex-persistedstate@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/vuex-persistedstate/-/vuex-persistedstate-4.0.0.tgz#ed82f266ca98c869a2aad9cb9880c2f608c05f3a"
integrity sha512-jDs+awbV9YD2A2F6S5zgtYq1Bjd8v0YldOK6HPv1EJZzGMse0FtZTREfXvA7zlVfq9MpmSZJNmYQVylfpZ5znQ==
dependencies:
deepmerge "^4.2.2"
shvl "^2.0.3"
vuex@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/vuex/-/vuex-4.0.2.tgz#f896dbd5bf2a0e963f00c67e9b610de749ccacc9"