前言:根据我上篇所实现的左边菜单栏之后,需要登录成功跳转home页面。主要分为三步。
第一步:创建三个ts文件结合pinia缓存登录信息和token
src\api\userTypes.ts
就是个接口类方便页面和另一个ts文件数据传递,其实也可以不用
export interface LoginResponse {userInfo: UserInfotoken: string}export interface UserInfo {user: string | null}
src\stores\modules\user.ts
这个ts就是结合pinia用于处理页面传过来要处理缓存的数据。
import { defineStore } from 'pinia'
import type {LoginResponse, UserInfo} from '@/api/userTypes'import { useStorage } from '@vueuse/core'export const useUserStore = defineStore('user', () => {const userInfoRef = useStorage('USER_INFO', {} as UserInfo, sessionStorage)const tokenRef = useStorage('TOKEN', '', sessionStorage)function setUserInfo(userInfo: UserInfo) {userInfoRef.value = userInfoconsole.log('userInfoRef====>',userInfoRef);}function setToken(token: string) {tokenRef.value = token}function toLogin(param: LoginResponse) { setToken(param.token) setUserInfo(param.userInfo)}function toLogout() {setUserInfo({} as UserInfo);setToken("");window.location.href = '/login'
}function getUsername() {return userInfoRef.value.user}function getToken() {return tokenRef.value}return { toLogin, toLogout, getToken, getUsername }
})
src\stores\counter.ts
import type {App} from 'vue'
import {createPinia} from 'pinia'const store = createPinia()export function useStore(app: App<Element>): void {app.use(store)
}export {store}
第二步:页面调用ts的登录处理方法,router下index.ts路径跳转处理
我这边处理是登录接口请求成功之后,再调用toLogin()方法。其实可以结合接口请求一起写,我这个是借鉴Vue + Ts 项目(七)—— 登录页面及登录校验,实现方式很多。我先结合自己项目实现功能。
包含登录操作的vue页面
import { useUserStore } from "@/stores/modules/user";
import { useRouter, useRoute } from "vue-router";
import { LoginResponse } from "@/api/userTypes";
// 引入这三//再在setup ()下第一行,切记一定要前排。不然router和route为空。
setup (){const userStore = useUserStore();const router = useRouter();const route = useRoute();const LoginResponseModel: Ref<LoginResponse> = ref({userInfo: {user:''},token: "",});// 再在登录回调成功的地方加上LoginResponseModel.userInfo ={user:res.user// 根据你自己的数据结构来} LoginResponseModel.token = res.tokenuserStore.toLogin(LoginResponseModel);// 这里LoginResponseModel,会报红。但是不影响流程。我后期看看怎么去红。哈哈哈哈哈,我还是太废了。const redirect = route.query.redirect as stringif (redirect) {router.replace(redirect)} else {router.replace('/combination/dashboard')}
不前排会报错Cannot read properties of undefined (reading 'replace')
,
也不要试图用useRouter()直接.replace会报错inject() can only be used inside setup() or functional components.
等一些问题
src\router\index.ts
主要是beforeEach方法。
import {createWebHistory, createRouter} from "vue-router";
import type {App} from 'vue'
// 获取所有路由
import routes from './routes'import { useUserStore } from "@/stores/modules/user";const router = createRouter({routes,// 这里使用历史记录模式history: createWebHistory()
})router.beforeEach((to, from, next) => {const userStore = useUserStore(); const isAuthenticated = userStore.getToken() && userStore.getToken() !== "";console.log('====isAuthenticated==',isAuthenticated);// isAuthenticated用于判断没有登录缓存,手动属于的路径,不会跳转成功。if (isAuthenticated) {next();} else {if (to.name === "login") {next();} else {next({ name: "login", query: { redirect: to.fullPath } });}}
});export const useRouter = (app: App<Element>): void => {app.use(router)
}
对了,别忘了配置login页面的路由src\router\modules\login.ts,把默认路径也是设置为登录页面
import type { RouteRecord } from '@/router/type'
import BasicLayout from "@/layouts/BasicLayout.vue";
import { CalendarTools } from '@vicons/carbon' const loginRoutes: RouteRecord[] = [{path: "/",name:'login',meta:{hidden: true},children: [{path: "/login",name: "login",component: () => import("@/views/login/login.vue"),},],},
]export default loginRoutes
到目前为止,登录成功后已经可以跳转了。先这样
第三步:检测token过期,登出处理
第三步先欠着。下周我再继续学习。毕竟周五了。我心已经起飞了。