(十)Vue3-huohuo-admin首屏和登录页面设计
本文已参与「新人创作礼」活动,一起开启掘金创作之路
从本篇陆续开始我们的页面开发啦!
首屏加载
项目启动后,我们打开网页,看到的是什么?—— 没错,是白屏(hiahiahiahia!)
白屏问题
首屏加载为什么会出现白屏?
其实在Vite
配置篇,就提到过Vite
很慢(),慢就慢在第一次打开页面,浏览器需要加载很长的时间来动态获取相应的资源。也就是从打开页面到渲染出我们想要的那个页面,会经历一个加载到渲染的过程,这个过程就会出现白屏的状况。
处理白屏的问题就是一次对前端项目的优化,除了Vite
配置篇提到的Vite
预构建处理(optimizeDeps
选项配置),我们还能做这些事情来帮助我们处理首屏加载慢,即白屏时间问题。
- 服务端
SSR
- 路由懒加载减少首屏页面加载的资源
- 服务端
Gzip
压缩,减少文件的体积,加快加载 - 使用骨架屏(页面在其他页面中跟后端数据交互的模块使用)
- 首页
loading
首页 loading
考虑到我们目前进程中,项目还非常小,且我们的页面开发从第一个看到的页面开始,所以先开发首页loading
吧。
这个loading
做成什么样,取决于你如何设计了(怎么好看怎么来!),这里参考 vben 吧(非专业人员,设计时间有限 ~~~)。
我们直接拿到vben
根目录下的index.html
,并进行修改
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vue3 huohuo admin</title>
</head>
<body>
<div id="app">
<style>
.app-loading {
display: flex;
width: 100%;
height: 100%;
justify-content: center;
align-items: center;
flex-direction: column;
background-color: #f4f7f9;
}
.app-loading .app-loading-wrap {
position: absolute;
top: 50%;
left: 50%;
display: flex;
transform: translate3d(-50%, -50%, 0);
justify-content: center;
align-items: center;
flex-direction: column;
}
.app-loading .dots {
display: flex;
padding: 98px;
justify-content: center;
align-items: center;
}
.app-loading .app-loading-title {
display: flex;
margin-top: 30px;
font-size: 30px;
color: rgb(0 0 0 / 85%);
justify-content: center;
align-items: center;
}
.app-loading .app-loading-logo {
display: block;
width: 90px;
margin: 0 auto;
margin-bottom: 20px;
}
.dot {
position: relative;
display: inline-block;
width: 48px;
height: 48px;
margin-top: 30px;
font-size: 32px;
transform: rotate(45deg);
box-sizing: border-box;
animation: antRotate 1.2s infinite linear;
}
.dot i {
position: absolute;
display: block;
width: 20px;
height: 20px;
background-color: #0065cc;
border-radius: 100%;
opacity: 30%;
transform: scale(0.75);
animation: antSpinMove 1s infinite linear alternate;
transform-origin: 50% 50%;
}
.dot i:nth-child(1) {
top: 0;
left: 0;
}
.dot i:nth-child(2) {
top: 0;
right: 0;
animation-delay: 0.4s;
}
.dot i:nth-child(3) {
right: 0;
bottom: 0;
animation-delay: 0.8s;
}
.dot i:nth-child(4) {
bottom: 0;
left: 0;
animation-delay: 1.2s;
}
@keyframes antRotate {
to {
transform: rotate(405deg);
}
}
@keyframes antRotate {
to {
transform: rotate(405deg);
}
}
@keyframes antSpinMove {
to {
opacity: 100%;
}
}
@keyframes antSpinMove {
to {
opacity: 100%;
}
}
</style>
<div class="app-loading">
<div class="app-loading-wrap">
<img src="/public/logo.png" class="app-loading-logo" alt="Logo" />
<div class="app-loading-dots">
<span class="dot dot-spin"><i></i><i></i><i></i><i></i></span>
</div>
<div class="app-loading-title">Vue3 huohuo admin</div>
</div>
</div>
</div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
效果展示
登录页面
loading
完事后,一般来说都会来到登录页面。登录页其实说简单也简单,说复杂也复杂,就看具体设计与业务需求了。通常包含这些点:
- UI 的设计
- 表单数据及其验证
- 登录注册方式/渠道
UI 设计
本项目的登录界面 UI 设计参考vue-pure-admin。
一般登录页主要包括:
- 背景块
- 项目 logo 及名称
- 项目简述、图示等美化模块(可选)
- 登录表单
- 其他系统性功能,例如正常/暗黑模式,国际化(时间关系目前阶段暂不开发,后续会出专门篇章)
登录模块开发
我们先创建登录页面及其路由,并把上篇的example
页面相关代码删除干净。
准备工作
背景模块开发
这里主要以背景图 + 插画的形式设计,我们在assets
文件夹下面创建专门的login
文件夹存放所有相关的图片。
svg 组件化
项目中会有很多地方用到svg
,而且通常我们会以组件的形式引入svg
,这非常方便我们的开发(比如可以*改变图片的颜色、尺寸等)。但是如果我们直接以组件的方式使用svg
,浏览器会报错。
这时候我们就需要借助一个插件来帮我们处理了—— vite-svg-loader。
我们进行安装并引入vite
的plugins
选项中。
pnpm install vite-svg-loader -D
接下来我们看看怎么使用
svg
组件,在这之前,我们先对login
模块做一定的代码分割,以便于我们编写出灵活且易于维护的代码(以前我们可能就是一个login.vue
就完事了~)。
首先,看看login
模块代码的分割
回到svg
组件,我们在assets
中存放了许多login
相关的svg
图片,这些其实都属于代码里的静态常量,我们统一在utils
中进行管理(统一引入并导出)。
这里的设计是引入并导出背景图、登录 logo,以及七日循环的插画图。
// src\views\login\utils\static.ts
import { computed } from "vue";
import bg from "/@/assets/login/bg.png";
import avatar from "/@/assets/login/avatar.svg?component";
import illustration0 from "/@/assets/login/illustration0.svg?component";
import illustration1 from "/@/assets/login/illustration1.svg?component";
import illustration2 from "/@/assets/login/illustration2.svg?component";
import illustration3 from "/@/assets/login/illustration3.svg?component";
import illustration4 from "/@/assets/login/illustration4.svg?component";
import illustration5 from "/@/assets/login/illustration5.svg?component";
import illustration6 from "/@/assets/login/illustration6.svg?component";
/* Show a different background every day */
const currentWeek = computed(() => {
switch (String(new Date().getDay())) {
case "0":
return illustration0;
case "1":
return illustration1;
case "2":
return illustration2;
case "3":
return illustration3;
case "4":
return illustration4;
case "5":
return illustration5;
case "6":
return illustration6;
default:
return illustration4;
}
});
export { bg, avatar, currentWeek };
然后我们在login.index
中引入。这里注意,我们的登录相关CSS
都放在style
下(login.css
),记得引入。
<!-- src\views\login\login.vue -->
<script setup lang="ts">
import { bg, avatar, currentWeek } from "./utils/static";
</script>
<template>
<img :src="bg" class="wave" />
<div class="login-container">
<div class="img">
<component :is="currentWeek" />
</div>
<div class="login-box">
<div class="login-form"><avatar class="avatar" /></div>
</div>
</div>
</template>
<style lang="scss" scoped>
@import url("/@/style/login.css");
</style>
svg 组件化是不是很好用呢!