不管是在页面跳转,还是页面加载时都少不了 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;
}