(十)Vue3-huohuo-admin 首屏及登录页设计

1,421 阅读4分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路

从本篇陆续开始我们的页面开发啦!

首屏加载

项目启动后,我们打开网页,看到的是什么?—— 没错,是白屏(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>

效果展示

image-20220516181219218

登录页面

loading完事后,一般来说都会来到登录页面。登录页其实说简单也简单,说复杂也复杂,就看具体设计与业务需求了。通常包含这些点:

  • UI 的设计
  • 表单数据及其验证
  • 登录注册方式/渠道

UI 设计

本项目的登录界面 UI 设计参考vue-pure-admin

一般登录页主要包括:

  • 背景块
  • 项目 logo 及名称
  • 项目简述、图示等美化模块(可选)
  • 登录表单
  • 其他系统性功能,例如正常/暗黑模式,国际化(时间关系目前阶段暂不开发,后续会出专门篇章)

登录模块开发

我们先创建登录页面及其路由,并把上篇的example页面相关代码删除干净。

image-20220517142839350

准备工作

背景模块开发

这里主要以背景图 + 插画的形式设计,我们在assets文件夹下面创建专门的login文件夹存放所有相关的图片。

image-20220519152901035

svg 组件化

项目中会有很多地方用到svg,而且通常我们会以组件的形式引入svg,这非常方便我们的开发(比如可以自由改变图片的颜色、尺寸等)。但是如果我们直接以组件的方式使用svg,浏览器会报错。

image-20220517155513624

这时候我们就需要借助一个插件来帮我们处理了—— vite-svg-loader

我们进行安装并引入viteplugins选项中。

pnpm install vite-svg-loader -D

image-20220517155945488

接下来我们看看怎么使用svg组件,在这之前,我们先对login模块做一定的代码分割,以便于我们编写出灵活且易于维护的代码(以前我们可能就是一个login.vue就完事了~)。

首先,看看login模块代码的分割

image-20220519153832638

回到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 组件化是不是很好用呢!