前言:根据我上篇所实现的左边菜单栏之后,需要登录成功跳转home页面。主要分为三步。
第一步:创建三个ts文件结合pinia缓存登录信息和token
src\api\userTypes.ts
就是个接口类方便页面和另一个ts文件数据传递,其实也可以不用
typescript
export interface LoginResponse {
userInfo: UserInfo
token: string
}
export interface UserInfo {
user: string | null
}
src\stores\modules\user.ts
这个ts就是结合pinia用于处理页面传过来要处理缓存的数据。
typescript
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 = userInfo
console.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
typescript
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页面
typescript
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.token
userStore.toLogin(LoginResponseModel);
// 这里LoginResponseModel,会报红。但是不影响流程。我后期看看怎么去红。哈哈哈哈哈,我还是太废了。
const redirect = route.query.redirect as string
if (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方法。
typescript
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,把默认路径也是设置为登录页面
typescript
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过期,登出处理
第三步先欠着。下周我再继续学习。毕竟周五了。我心已经起飞了。