vue3项目中在页面跳转时展示 loading page

不管是在页面跳转,还是页面加载时都少不了 loading page,如果说没有加载页,用户体验感会极度的不好。
试想,谁会想在页面跳转或页面刷新的时候被页面的白屏闪一下。当然这不仅仅只有这点作用,如果遇到页面加载时间过长,
页面加载时样式还没渲染完成,也会使得用户体验感差。所以,加载页在项目中是必不可少的。

下面是一种 loading page 的实践,要实现下面的这种方式需要:pinia、Vue

首先,我们需要在写一个 store 方法,用于从 body 中删除类名。

import { ref } from "vue";
import { defineStore } from "pinia";

export const useBodyStore = defineStore("body", () => {
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  const classes = ref<any>({});

  function removeBodyClassName(className: string) {
    document.body.classList.remove(className);
  }

  return {
    removeBodyClassName,
  };
});

接着,我们在 App.vue 中引入。这里的意思是:在组件挂载之后,执行回调函数。
在回调函数中,使用 nextTick 函数等待 DOM 更新完成后,调用 bodyStore 中的 removeBodyClassName 方法,
并传递 page-loading 作为参数。这样可以在页面加载完成后从页面主体的类名中移除 page-loading 类。

<script setup lang="ts">
import { onMounted, nextTick } from "vue";
import { useBodyStore } from "./store/body";

const bodyStore = useBodyStore();

onMounted(() => {
  nextTick(() => {
    bodyStore.removeBodyClassName("page-loading");
  });
});
</script>

<template>
  <router-view v-slot="{ Component }">
    <transition>
      <component :is="Component" />
    </transition>
  </router-view>
</template>

<style lang="scss">
@import "normalize.css";
@import "@/assets/styles/normal.css";
</style>

最后的重点来了,在 html 中给 body 加上类名 page-loading,同时把加载页所需的 html 结构写在这里。
当然,别忘了将 css 样式也在这里引入。

其实原理很简单,由于页面渲染的顺序是从上往下的,所以加载顺序是 body(.page-lading)->div(#app)->div(#loading-screen .loading-screen)->script
由于主要内容(#app)的渲染顺序在最后(渲染的时候还需要一点时间),并且加载页的样式也在这里已经引入了。所以就有加载页的效果

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <!-- 引入加载 css -->
    <link rel="stylesheet" href="/loading.css" />
    <title>studTWork</title>
  </head>
  <body class="page-loading">
    <div id="app"></div>

    <!-- 加载页 html -->
    <div id="loading-screen" class="loading-screen">
      <img src="/favicon.svg" class="dark-logo" alt="dark logo" />
      <img src="/favicon.svg" class="light-logo" alt="light logo" />
      <span>Loading ...</span>
    </div>

    <script type="module" src="/src/main.ts"></script>
  </body>
</html>

注意:加载页的样式和结果尽量精简,这样加载页的加载速度才会快。

这里贴一个加载页的样式

body.page-loading {
  margin: 0;
  height: 100%;
  overflow: hidden;
}

.loading-screen {
  display: none;
}

.page-loading .loading-screen {
  position: absolute;
  z-index: 1000;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  font-family: Inter, Helvetica, "sans-serif";
  background-color: #f9f9f9;
  color: #5e6278;
  line-height: 1;
  font-size: 14px;
  font-weight: 400;
}

.page-loading .loading-screen span {
  color: #5e6278;
  transition: none !important;
  -webkit-font-smoothing: antialiased;
}

.page-loading .loading-screen img {
  margin-left: calc(100vw - 100%);
  margin-bottom: 30px;
  height: 30px !important;
}

html[class="dark"] .page-loading .loading-screen {
  background-color: #151521;
  color: #ffffff;
}

.loading-screen .dark-logo {
  display: none;
}

.loading-screen .light-logo {
  display: block;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

画一个圆_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值