模拟场景:
当用户登录后,后台会返回一个token给前端,前端下次进入首页后,会先判断token是否过期,如果过期自动进入登录页面。
配置路由:
1.安装
npm install vue-router@4
2.安装后在src
目录下创建router文件夹
,并创建index.js
代码如下:
// vue-router中提供3种的路由模式
import { createWebHistory, createRouter } from 'vue-router'
import { checktoken } from '../request/api';const routes = [{path: '/',name: "home",component: () => import('../components/Pages/Home.vue'),},{path: '/login',name: 'login',component: () => import('../components/Pages/Login.vue'),}
]const router = createRouter({// 路由的模式history: createWebHistory(),// 路由规则routes
})//导航守卫 导航前做点操作
router.beforeEach(async (to, from, next) => {// 编写一个函数来检查 token 是否有效if (to.name == 'home' && await checkTokenValidity()) {// 如果进入首页且未认证,则重定向到登录页next({ name: 'login' });} else {// 其他情况允许通过next();}
});async function checkTokenValidity() {// 获取 tokenconst token = localStorage.getItem('token');if (token) {// 使用 ' ' 分割字符串const arr = token.split(' ');let tokenstr = arr[1];return await checktoken({ token: tokenstr })}return true
}export default router
配置axios:
1.安装
npm install axios
2.在src
中创建request文件夹
,并创建http.js和api.js
3.http.js
用于封装axios
实例 代码如下:
// 在http.js中引入axios
import axios from 'axios'; // 引入axios
import { ElMessage } from 'element-plus'const config={// `url` 是用于请求的服务器 URLurl: '/api',// `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。// 它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URLbaseURL: 'http://localhost:56030/api',// `timeout` 指定请求超时的毫秒数(0 表示无超时时间)// 如果请求话费了超过 `timeout` 的时间,请求将被中断timeout: 10000,}const requests = axios.create(config);//请求拦截器(可以在请求发出去之前,做一些事情)
requests.interceptors.request.use((config) => {return config;});//响应拦截器(在数据返回之后,做一些事情)requests.interceptors.response.use((res) => {return res.data;},(err) => {console.log(err);ElMessage.error(err.response.data)})export default requests;
4.api.js
用于对接口的统一管理 代码如下:
import requests from "./http"; //引入二次封装的axios
export const login = (params)=>requests({url:'/Account/login ',method:'post',data:params});
export const checktoken = (params)=>requests({url:'/Account/checktoken ',method:'post',data:params});
对路由和封装接口的使用
1.登录login.vue
组件,这里只看用法即可。 代码如下:
<template><el-card class="box-card"><el-text class="title" type="warning" size="large">Metadata科技屋</el-text><div style="margin: 40px;"></div><el-form label-position="top" label-width="100px" :model="formLabelAlign" style="max-width: 460px"><el-form-item label="账号"><el-input v-model="formLabelAlign.accountNumber" /></el-form-item><el-form-item label="密码"><el-input v-model="formLabelAlign.password" type="password" /></el-form-item><el-button class="loginbut" type="primary" @click="onSubmit">登录</el-button></el-form></el-card>
</template><script setup>
import { reactive } from 'vue'
import { login } from '../../request/api';
import { ElMessage } from 'element-plus'
import { useRouter } from 'vue-router';
const router = useRouter();const formLabelAlign = reactive({accountNumber: 'admin',password: '123456'
})const onSubmit = async () => {var token = await login(formLabelAlign)if (token) {// 存储 token [Authorize(AuthenticationSchemes = "Bearer")]localStorage.setItem('token',"Bearer "+token);ElMessage({message: '登录成功',type: 'success',})// 字符串路径router.push('/');}
}</script><style scoped>
.el-card {position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);
}.box-card {width: 480px;height: 320px;
}.title {position: absolute;left: 50%;transform: translate(-50%, -50%);
}.loginbut {float: right;
}
</style>
登录成功后的路由跳转需要引用这句代码:
import { useRouter } from 'vue-router';
const router = useRouter();// 字符串路径
router.push('/');
main.js代码如下:
import { createApp } from 'vue'// 图标和组件需要分开引入
import ElementPlus from 'element-plus'; // 引入 ElementPlus 组件import 'element-plus/dist/index.css'
// Element Plus
import 'element-plus/theme-chalk/index.css' // 引入 ElementPlus 组件样式import 'element-plus/theme-chalk/dark/css-vars.css'import { Edit } from '@element-plus/icons-vue' // 按需引入 Icon 图标 import router from './router/index'import App from './App.vue'const app = createApp(App)
app.use(router)
app.component('Edit', Edit)
app.use(ElementPlus) // 全局挂载 ElementPlus
app.mount('#app')
app.vue
代码:
<script>export default {};</script><template><router-view></router-view>
</template><style scoped>.common-layout
{
height: 100vh;
}
.el-container
{height: 100vh;
}</style>
给出main.js代码和app.vue
代码,可以更方便的看出路由的使用方式。