forked from UzTech/Vue3-typescript-demo
vuex持久化
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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 } })
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
13
yarn.lock
13
yarn.lock
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user