登录页添加以及路由权限添加

This commit is contained in:
bestlee 2026-06-23 17:28:13 +08:00
parent d99c972b6e
commit 3da01972a3
5 changed files with 149 additions and 17 deletions

BIN
public/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@ -1,8 +1,6 @@
import './assets/main.css' import './assets/main.css'
import { createApp } from 'vue' import { createApp } from 'vue'
import { createPinia } from 'pinia' import { createPinia } from 'pinia'
import App from './App.vue' import App from './App.vue'
import router from './router' import router from './router'
import 'amfe-flexible' import 'amfe-flexible'
@ -11,5 +9,4 @@ const app = createApp(App)
app.use(createPinia()) app.use(createPinia())
app.use(router) app.use(router)
app.mount('#app') app.mount('#app')

View File

@ -1,19 +1,68 @@
import { createRouter, createWebHistory } from 'vue-router' import { createRouter, createWebHistory } from 'vue-router'
// 静态路由(公共页面)
const constantRoutes = [
{
path: '/',
redirect: '/login'
},
{
path: '/login',
name: 'login',
component: () => import('../views/login/index.vue'),
},
{
path: '/404',
name: 'NotFound',
component: () => import('../views/error/404.vue'),
},
];
const router = createRouter({ const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL), history: createWebHistory(),
routes: [ routes: constantRoutes,
{ })
path: '/',
name: 'login', // 动态路由(需要权限的页面)
component: () => import('../views/login/index.vue'), // 注意:这些路由不会在一开始注册,而是在守卫中动态添加
const asyncRoutes = [
{
path: '/applyList',
name: 'applyList',
component: () => import('../views/applyList/index.vue'),
meta: {
title: '申请列表',
}, },
{ },
path: '/applyList', ]
name: 'applyList',
component: () => import('../views/applyList/index.vue'), // 标志位:是否已添加动态路由
}, let isRoutesAdded = false
], router.beforeEach((to, from, next) => {
const token = localStorage.getItem('token')
if (token) {
// 关键:有 token 但业务路由还没挂载 => 动态添加(仅一次)
if (!isRoutesAdded) {
asyncRoutes.forEach(route => {
router.addRoute(route)
})
// 必须加载最后面
router.addRoute({
path: '/:pathMatch(.*)*',
redirect: '/404'
});
isRoutesAdded = true
next({ ...to })
} else {
next()
}
} else {
if (to.path === '/login' || to.path === '/404') {
next()
} else {
next({ path: '/login' })
}
}
}) })
export default router export default router

3
src/views/error/404.vue Normal file
View File

@ -0,0 +1,3 @@
<template>
<div>404</div>
</template>

View File

@ -1,12 +1,95 @@
<script setup> <script setup>
import { ref } from 'vue'
import router from '@/router'
const btnLoading = ref(false)
const formData = ref({
username: '',
password: '',
})
//
const onSubmit = (values) => {
btnLoading.value = true;
console.log(values);
setTimeout(() => {
btnLoading.value = false;
router.push({ path: '/applyList' });
}, 1000);
}
</script> </script>
<template> <template>
<div class="login">login</div> <div class="main">
<div class="box">
<div class="logo">
<img src="/public/logo.png" alt="">
<p class="login">登录</p>
</div>
<van-form @submit="onSubmit" size="small" label-width="1.2rem">
<van-cell-group inset>
<van-field
v-model="formData.username"
name="username"
label="用户名"
placeholder="请输入用户名"
:rules="[{ required: true, message: '请输入用户名' }]"
/>
<van-field
v-model="formData.password"
type="password"
name="password"
label="密码"
placeholder="请输入密码"
:rules="[{ required: true, message: '请输入密码' }]"
/>
</van-cell-group>
<van-button class="btn" :loading="btnLoading" round block size="small" type="primary" native-type="submit">登录</van-button>
</van-form>
</div>
</div>
</template> </template>
<style scoped> <style scoped>
:deep(.van-cell-group--inset) {
margin: 0;
}
.main {
width: 100%;
min-height: 100vh;
height: 100%;
background: linear-gradient(to bottom, #3d59aa, #4d76c1, #64a1e1);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 10px;
}
.box {
width: 80%;
background: #fff;
border-radius: 8px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 20px 12px
}
.logo {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 10px;
}
.logo img {
width: 30px;
height: 30px;
margin-right: 10px;
}
.login { .login {
font-size: 14px; font-size: 20px;
}
.btn {
margin-top: 10px;
} }
</style> </style>