登录页优化

This commit is contained in:
JenniferW 2026-01-09 17:35:52 +08:00
parent 7939a35ca1
commit d47a1b7cdb
5 changed files with 126 additions and 160 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 725 KiB

After

Width:  |  Height:  |  Size: 867 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

After

Width:  |  Height:  |  Size: 137 KiB

View File

@ -2,7 +2,11 @@
<el-breadcrumb class="app-breadcrumb" separator="/"> <el-breadcrumb class="app-breadcrumb" separator="/">
<transition-group name="breadcrumb"> <transition-group name="breadcrumb">
<el-breadcrumb-item v-for="(item, index) in levelList" :key="item.path"> <el-breadcrumb-item v-for="(item, index) in levelList" :key="item.path">
<span v-if="item.redirect === 'noRedirect' || index == levelList.length - 1" class="no-redirect">{{ item.meta.title }}</span> <span
v-if="item.redirect === 'noRedirect' || index == levelList.length - 1"
class="no-redirect"
>{{ item.meta.title }}</span
>
<a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a> <a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a>
</el-breadcrumb-item> </el-breadcrumb-item>
</transition-group> </transition-group>
@ -10,77 +14,82 @@
</template> </template>
<script setup> <script setup>
import usePermissionStore from '@/store/modules/permission' import usePermissionStore from "@/store/modules/permission";
const route = useRoute() const route = useRoute();
const router = useRouter() const router = useRouter();
const permissionStore = usePermissionStore() const permissionStore = usePermissionStore();
const levelList = ref([]) const levelList = ref([]);
function getBreadcrumb() { function getBreadcrumb() {
// only show routes with meta.title // only show routes with meta.title
let matched = [] let matched = [];
const pathNum = findPathNum(route.path) const pathNum = findPathNum(route.path);
// multi-level menu // multi-level menu
if (pathNum > 2) { if (pathNum > 2) {
const reg = /\/\w+/gi const reg = /\/\w+/gi;
const pathList = route.path.match(reg).map((item, index) => { const pathList = route.path.match(reg).map((item, index) => {
if (index !== 0) item = item.slice(1) if (index !== 0) item = item.slice(1);
return item return item;
}) });
getMatched(pathList, permissionStore.defaultRoutes, matched) getMatched(pathList, permissionStore.defaultRoutes, matched);
} else { } else {
matched = route.matched.filter((item) => item.meta && item.meta.title) matched = route.matched.filter((item) => item.meta && item.meta.title);
} }
// //
if (!isDashboard(matched[0])) { // if (!isDashboard(matched[0])) {
matched = [{ path: "/index", meta: { title: "首页" } }].concat(matched) // matched = [{ path: "/index", meta: { title: "" } }].concat(matched)
} // }
levelList.value = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false) levelList.value = matched.filter(
(item) => item.meta && item.meta.title && item.meta.breadcrumb !== false
);
} }
function findPathNum(str, char = "/") { function findPathNum(str, char = "/") {
let index = str.indexOf(char) let index = str.indexOf(char);
let num = 0 let num = 0;
while (index !== -1) { while (index !== -1) {
num++ num++;
index = str.indexOf(char, index + 1) index = str.indexOf(char, index + 1);
} }
return num return num;
} }
function getMatched(pathList, routeList, matched) { function getMatched(pathList, routeList, matched) {
let data = routeList.find(item => item.path == pathList[0] || (item.name += '').toLowerCase() == pathList[0]) let data = routeList.find(
(item) =>
item.path == pathList[0] || (item.name += "").toLowerCase() == pathList[0]
);
if (data) { if (data) {
matched.push(data) matched.push(data);
if (data.children && pathList.length) { if (data.children && pathList.length) {
pathList.shift() pathList.shift();
getMatched(pathList, data.children, matched) getMatched(pathList, data.children, matched);
} }
} }
} }
function isDashboard(route) { function isDashboard(route) {
const name = route && route.name const name = route && route.name;
if (!name) { if (!name) {
return false return false;
} }
return name.trim() === 'Index' return name.trim() === "Index";
} }
function handleLink(item) { function handleLink(item) {
const { redirect, path } = item const { redirect, path } = item;
if (redirect) { if (redirect) {
router.push(redirect) router.push(redirect);
return return;
} }
router.push(path) router.push(path);
} }
watchEffect(() => { watchEffect(() => {
// if you go to the redirect page, do not update the breadcrumbs // if you go to the redirect page, do not update the breadcrumbs
if (route.path.startsWith('/redirect/')) { if (route.path.startsWith("/redirect/")) {
return return;
} }
getBreadcrumb() getBreadcrumb();
}) });
getBreadcrumb() getBreadcrumb();
</script> </script>
<style lang='scss' scoped> <style lang='scss' scoped>

View File

@ -1,6 +1,6 @@
<template> <template>
<div class="login"> <div class="login">
<!-- <img src="../assets/images/444.png" class="logo" alt="logo" /> --> <img src="../assets/images/logo.png" class="logo" alt="logo" />
<div class="login-container"> <div class="login-container">
<!-- 左侧插图区域 --> <!-- 左侧插图区域 -->
<!-- <div class="login-left"> <!-- <div class="login-left">
@ -26,7 +26,7 @@
type="text" type="text"
size="large" size="large"
auto-complete="off" auto-complete="off"
placeholder="请输入号" placeholder="请输入号"
> >
<template #prefix <template #prefix
><svg-icon icon-class="user" class="el-input__icon input-icon" ><svg-icon icon-class="user" class="el-input__icon input-icon"
@ -123,8 +123,8 @@ const router = useRouter();
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const loginForm = ref({ const loginForm = ref({
username: "admin", username: "",
password: "admin123", password: "",
rememberMe: false, rememberMe: false,
code: "", code: "",
uuid: "", uuid: "",
@ -143,7 +143,7 @@ const showPassword = ref(false);
// //
const loginRules = computed(() => { const loginRules = computed(() => {
const rules = { const rules = {
username: [{ required: true, trigger: "blur", message: "请输入您的号" }], username: [{ required: true, trigger: "blur", message: "请输入您的号" }],
password: [{ required: true, trigger: "blur", message: "请输入您的密码" }], password: [{ required: true, trigger: "blur", message: "请输入您的密码" }],
}; };
if (captchaEnabled.value) { if (captchaEnabled.value) {
@ -241,100 +241,45 @@ getCookie();
justify-content: center; justify-content: center;
align-items: center; align-items: center;
min-height: 100vh; min-height: 100vh;
width: 100%;
position: relative;
background-image: url("../assets/images/bg.jpg"); background-image: url("../assets/images/bg.jpg");
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: 100% 100%; /* 使背景图片完全覆盖容器 */ background-size: 100% 100%;
background-clip: padding-box; background-clip: padding-box;
overflow: visible; overflow: visible;
background-position: center; background-position: center;
background-attachment: fixed; // background-attachment: fixed;
// background: linear-gradient(to bottom, #449ac6 0%, #5dbbe4 100%); box-sizing: border-box;
// background: linear-gradient(135deg, #e3f2f5 0%, #d0e8eb 50%, #c5e3e6 100%); }
// position: relative; .logo {
// padding: 0; position: absolute;
// overflow: hidden; top: 70px;
left: 80px;
// // - width: 30%;
// &::before { }
// content: ""; .login-container {
// position: absolute; display: flex;
// bottom: 0; width: 100%;
// left: 0; max-width: 1400px;
// width: 45%; min-height: 100vh;
// height: 280px; position: relative;
// min-height: 220px; z-index: 1;
// background-image: url("../assets/images/logo_left.png"); box-sizing: border-box;
// background-repeat: no-repeat; justify-content: flex-end;
// background-position: left bottom; align-items: center;
// background-size: contain; padding: 40px 60px;
// opacity: 0.5;
// z-index: 0;
// pointer-events: none;
// filter: blur(0.5px);
// }
// // -
// &::after {
// content: "";
// position: absolute;
// bottom: 0;
// right: 0;
// width: 45%;
// height: 280px;
// min-height: 220px;
// background-image: url("../assets/images/logo_leftright.png");
// background-repeat: no-repeat;
// background-position: right bottom;
// background-size: contain;
// opacity: 0.5;
// z-index: 0;
// pointer-events: none;
// filter: blur(0.5px);
// }
} }
// .logo {
// position: absolute;
// top: 35px;
// left: 45px;
// width: 18%;
// }
// .login-container {
// display: flex;
// width: 100%;
// max-width: 1400px;
// height: 100vh;
// position: relative;
// z-index: 1;
// }
// .login-left {
// flex: 1;
// display: flex;
// justify-content: center;
// align-items: center;
// padding: 60px 40px;
// position: relative;
// // .login-illustration {
// // width: 100%;
// // max-width: 650px;
// // height: auto;
// // object-fit: contain;
// // filter: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.08));
// // }
// }
.login-right { .login-right {
flex: 1;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
align-items: end; align-items: center;
left: 70%;
padding: 40px 60px;
position: relative; position: relative;
box-sizing: border-box;
width: 100%;
max-width: 500px;
} }
.title-text { .title-text {
@ -346,18 +291,23 @@ getCookie();
font-weight: 600; font-weight: 600;
letter-spacing: 0.5px; letter-spacing: 0.5px;
line-height: 1.4; line-height: 1.4;
width: 100%;
box-sizing: border-box;
} }
.login-form { .login-form {
border-radius: 16px; border-radius: 16px;
background: #ffffff; background: #ffffff;
width: 100%; width: 420px;
min-width: 420px;
max-width: 420px; max-width: 420px;
padding: 50px 40px; padding: 50px 40px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12); box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);
box-sizing: border-box;
flex-shrink: 0;
:deep(.el-form-item) { :deep(.el-form-item) {
margin-bottom: 10px; margin-bottom: 15px;
&:last-child { &:last-child {
margin-bottom: 0; margin-bottom: 0;
@ -509,54 +459,61 @@ getCookie();
// //
@media (max-width: 1024px) { @media (max-width: 1024px) {
.login-container { .login-container {
flex-direction: column; justify-content: center;
} padding: 40px 40px;
.login-left {
flex: 0 0 auto;
padding: 30px 20px;
max-height: 40vh;
.login-illustration {
max-width: 400px;
}
} }
.login-right { .login-right {
flex: 1; max-width: 100%;
padding: 30px 20px; width: 100%;
} }
.login { .login-form {
&::before, width: 100%;
&::after { max-width: 420px;
height: 180px; min-width: 320px;
opacity: 0.3; padding: 45px 35px;
}
} }
} }
@media (max-width: 768px) { @media (max-width: 768px) {
.login-left { .login-container {
display: none; padding: 30px 20px;
justify-content: center;
align-items: center;
} }
.login-right { .login-right {
width: 100%; width: 100%;
padding: 30px 20px;
}
.login-form {
padding: 35px 28px 28px 28px;
max-width: 100%; max-width: 100%;
} }
.login { .login-form {
&::before, width: 100%;
&::after { max-width: 100%;
height: 150px; min-width: 280px;
opacity: 0.25; padding: 35px 28px;
} }
.title-text {
font-size: 28px;
margin-bottom: 30px;
}
}
@media (max-width: 480px) {
.login-container {
padding: 20px 15px;
}
.login-form {
padding: 30px 20px;
border-radius: 12px;
}
.title-text {
font-size: 24px;
margin-bottom: 25px;
} }
} }
</style> </style>