fix: 修改了退出登录的逻辑,在登录和刷新页面时会重载路由、修改了初始化项目加载动画的逻辑
This commit is contained in:
parent
371b86a3dc
commit
9cf79cb079
@ -4,10 +4,15 @@
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/src/assets/logo/snow.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="stylesheet" href="/css/loading.css" type="text/css" />
|
||||
<title><%= title %></title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<div id="app">
|
||||
<div class="init-page">
|
||||
<div class="snow-loader"></div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
61
public/css/loading.css
Normal file
61
public/css/loading.css
Normal file
@ -0,0 +1,61 @@
|
||||
body {
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
.init-page {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
left: 0;
|
||||
top: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: #fff;
|
||||
}
|
||||
/* HTML: <div class="snow-loader"></div> */
|
||||
.snow-loader {
|
||||
width: 45px;
|
||||
aspect-ratio: 1;
|
||||
|
||||
--c: no-repeat linear-gradient(rgb(22, 93, 255) 0 0);
|
||||
|
||||
background:
|
||||
var(--c) 0% 50%,
|
||||
var(--c) 50% 50%,
|
||||
var(--c) 100% 50%;
|
||||
background-size: 20% 100%;
|
||||
animation: l1 1s infinite linear;
|
||||
}
|
||||
|
||||
@keyframes l1 {
|
||||
0% {
|
||||
background-size:
|
||||
20% 100%,
|
||||
20% 100%,
|
||||
20% 100%;
|
||||
}
|
||||
33% {
|
||||
background-size:
|
||||
20% 10%,
|
||||
20% 100%,
|
||||
20% 100%;
|
||||
}
|
||||
50% {
|
||||
background-size:
|
||||
20% 100%,
|
||||
20% 10%,
|
||||
20% 100%;
|
||||
}
|
||||
66% {
|
||||
background-size:
|
||||
20% 100%,
|
||||
20% 100%,
|
||||
20% 10%;
|
||||
}
|
||||
100% {
|
||||
background-size:
|
||||
20% 100%,
|
||||
20% 100%,
|
||||
20% 100%;
|
||||
}
|
||||
}
|
||||
@ -5,7 +5,6 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { loadingPage } from "@/utils/loading-page";
|
||||
import { useThemeMethods } from "@/hooks/useThemeMethods";
|
||||
|
||||
// 初始化主题
|
||||
@ -14,12 +13,6 @@ const onTheme = () => {
|
||||
initTheme();
|
||||
};
|
||||
onTheme();
|
||||
|
||||
// 加载动画
|
||||
loadingPage.start();
|
||||
onMounted(() => {
|
||||
loadingPage.done(200);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@ -112,7 +112,6 @@ import { useI18n } from "vue-i18n";
|
||||
import { Modal } from "@arco-design/web-vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { storeToRefs } from "pinia";
|
||||
import { useRoutesConfigStore } from "@/store/modules/route-config";
|
||||
import { useUserInfoStore } from "@/store/modules/user-info";
|
||||
import { useThemeConfig } from "@/store/modules/theme-config";
|
||||
import { useThemeMethods } from "@/hooks/useThemeMethods";
|
||||
@ -194,9 +193,6 @@ const logOut = () => {
|
||||
// 用户退出
|
||||
const store = useUserInfoStore();
|
||||
await store.logOut();
|
||||
// 重置路由树
|
||||
const route = useRoutesConfigStore();
|
||||
await route.resetRoute();
|
||||
router.replace("/login");
|
||||
return true;
|
||||
} catch {
|
||||
|
||||
@ -9,7 +9,6 @@
|
||||
<script setup lang="ts">
|
||||
import { storeToRefs } from "pinia";
|
||||
import { useThemeConfig } from "@/store/modules/theme-config";
|
||||
import { loadingPage } from "@/utils/loading-page";
|
||||
|
||||
const themeStore = useThemeConfig();
|
||||
const { layoutType } = storeToRefs(themeStore);
|
||||
@ -20,11 +19,6 @@ const layouts: any = {
|
||||
layoutHead: defineAsyncComponent(() => import("@/layout/layout-head/index.vue")),
|
||||
layoutMixing: defineAsyncComponent(() => import("@/layout/layout-mixing/index.vue"))
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
// 页面渲染完毕,结束loading
|
||||
loadingPage.done(200);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@ -7,7 +7,6 @@ import { storeToRefs } from "pinia";
|
||||
import { useUserInfoStore } from "@/store/modules/user-info";
|
||||
import { useRoutesConfigStore } from "@/store/modules/route-config";
|
||||
import { useRoutingMethod } from "@/hooks/useRoutingMethod";
|
||||
import { loadingPage } from "@/utils/loading-page";
|
||||
|
||||
/**
|
||||
* 创建vue的路由示例
|
||||
@ -32,16 +31,16 @@ const router = createRouter({
|
||||
* 1、去登录页,无token,放行
|
||||
* 2、没有token,直接重定向到登录页
|
||||
* 3、去登录页,有token,直接重定向到home页
|
||||
* 4、去非登录页,有token,校验是否动态添加过路由,添加过则放行,未添加则执行路由初始化
|
||||
* 4、去非登录页,有token,若是从登录页而来则重载路由,若是刷新页面则重载路由,重载后重新跳转
|
||||
* 注意:
|
||||
* 全局routeTree不能持久化缓存
|
||||
* 页面刷新会导致addRoute动态添加的路由失效,需要重新初始化路由
|
||||
*/
|
||||
router.beforeEach(async (to, _, next) => {
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
NProgress.start(); // 开启进度条
|
||||
const store = useUserInfoStore(pinia);
|
||||
const { token } = storeToRefs(store);
|
||||
// console.log("去", to, "来自", from);
|
||||
console.log("去", to, "来自", from);
|
||||
// next()内部加了path等于跳转指定路由会再次触发router.beforeEach,内部无参数等于放行,不会触发router.beforeEach
|
||||
if (to.path === "/login" && !token.value) {
|
||||
// 1、去登录页,无token,放行
|
||||
@ -59,19 +58,22 @@ router.beforeEach(async (to, _, next) => {
|
||||
const routeStore = useRoutesConfigStore(pinia);
|
||||
const { routeTree } = storeToRefs(routeStore);
|
||||
|
||||
// 从登录页跳转过来,需要重置路由(登录后触发)
|
||||
if (from.path === "/login") {
|
||||
await routeStore.initSetRouter();
|
||||
}
|
||||
|
||||
// 获取外链路由的处理函数
|
||||
// 所有的路由正常放行,只不过额外判断是否是外链,如果是,则打开新窗口跳转外链
|
||||
// 外链的页面依旧正常打开,只不过不会参与缓存与tabs显示,符合路由跳转的直觉
|
||||
const { openExternalLinks } = useRoutingMethod();
|
||||
|
||||
// 如果缓存的路由是0,则说明未动态添加路由,先添加再跳转
|
||||
// 如果缓存的路由是0,则说明未动态添加路由,先添加再跳转(页面刷新时触发)
|
||||
// 解决刷新页面404的问题
|
||||
if (routeTree.value.length == 0) {
|
||||
loadingPage.start();
|
||||
await routeStore.initSetRouter();
|
||||
// 处理外链跳转
|
||||
openExternalLinks(to);
|
||||
// 处理完重新跳转
|
||||
next({ path: to.path, query: to.query });
|
||||
} else {
|
||||
// 处理外链跳转
|
||||
|
||||
@ -1,110 +1,110 @@
|
||||
import { defineStore } from "pinia";
|
||||
import router from "@/router/index";
|
||||
import { RouteRecordRaw } from "vue-router";
|
||||
import { getMenuListAPI } from "@/api/modules/system/index";
|
||||
import { moduleReplacement, linearArray } from "@/router/route-output";
|
||||
/**
|
||||
* 路由列表
|
||||
* @methods setRouteNames 设置路由名称集合
|
||||
* @methods setTabs 添加tabs标签页
|
||||
* @methods setCurrentRoute 设置系统内的当前路由
|
||||
* @methods removeTabsList 删除tabs页的指定路由
|
||||
* @methods removeRouteName 删除缓存路由名,用于取消页面缓存,单个删除
|
||||
* @methods removeRouteNames 删除缓存路由名,用于取消页面缓存,批量删除
|
||||
* @methods initSetRouter 路由初始化
|
||||
*/
|
||||
export const useRoutesConfigStore = defineStore("route-config", {
|
||||
state: (): any => ({
|
||||
routeTree: [], // 有访问权限的路由树
|
||||
routeList: [], // 有访问权限的一维路由数组
|
||||
cacheRoutes: [], // 所有可缓存路由的路由名
|
||||
tabsList: [], // 标签页数据
|
||||
currentRoute: {} // 当前路由
|
||||
}),
|
||||
actions: {
|
||||
/**
|
||||
* 设置可缓存路由的路由名
|
||||
* @param {string} name 路由名
|
||||
*/
|
||||
setRouteNames(name: string) {
|
||||
let state = this.cacheRoutes.some((item: string) => item === name);
|
||||
if (state) return;
|
||||
this.cacheRoutes.push(name);
|
||||
},
|
||||
/**
|
||||
* 添加tabs标签页
|
||||
* @param {object} data 当前tabs路由
|
||||
*/
|
||||
setTabs(data: Menu.MenuOptions) {
|
||||
// 当前路由在tags中是否存在,不存在则缓存
|
||||
let isExist = this.tabsList.some((item: Menu.MenuOptions) => item.name === data.name);
|
||||
if (isExist) return;
|
||||
this.tabsList.push(data);
|
||||
},
|
||||
/**
|
||||
* 设置系统内的当前路由数据
|
||||
* @param {object} data 当前路由
|
||||
*/
|
||||
setCurrentRoute(data: Menu.MenuOptions) {
|
||||
if (this.currentRoute.name && data.name === this.currentRoute.name) return;
|
||||
this.currentRoute = data;
|
||||
},
|
||||
/**
|
||||
* 删除tabs页的指定路由
|
||||
* @param {string} key 路由name
|
||||
*/
|
||||
removeTabsList(key: string) {
|
||||
const index = this.tabsList.findIndex((item: Menu.MenuOptions) => item.name === key);
|
||||
if (this.tabsList[index].meta.affix) return;
|
||||
if (index === -1) return;
|
||||
this.tabsList.splice(index, 1);
|
||||
},
|
||||
/**
|
||||
* 删除缓存路由名,用于取消页面缓存,单个删除
|
||||
* @param {string} key 路由名
|
||||
*/
|
||||
removeRouteName(key: string) {
|
||||
const index = this.cacheRoutes.findIndex((item: string) => item === key);
|
||||
if (index === -1) return;
|
||||
this.cacheRoutes.splice(index, 1);
|
||||
},
|
||||
/**
|
||||
* 删除缓存路由名,用于取消页面缓存,批量删除
|
||||
* @param {Array} list 路由名
|
||||
*/
|
||||
removeRouteNames(list: Array<string>) {
|
||||
this.cacheRoutes = this.cacheRoutes.filter((item: string) => !list.includes(item));
|
||||
},
|
||||
/**
|
||||
* 重置routeTree路由树
|
||||
*/
|
||||
async resetRoute() {
|
||||
this.routeTree = [];
|
||||
},
|
||||
/**
|
||||
* 路由初始化
|
||||
* 1、将模块设置为真实模块
|
||||
* 2、存储路由树,用于生成菜单
|
||||
* 3、根据树生成一维路由数组
|
||||
* 4、动态添加路由,设置完整的路由,二维路由:顶层路由 + 二级的一维路由
|
||||
* 5、动态添加路由
|
||||
* 6、缓存一维路由
|
||||
*/
|
||||
async initSetRouter() {
|
||||
// 1、获取过滤角色权限后的树,后端做排序处理
|
||||
let { data } = await getMenuListAPI();
|
||||
// 2、将模块设置为真实模块
|
||||
let tree = moduleReplacement(data);
|
||||
// 3、存储路由树,用于生成菜单
|
||||
this.routeTree = tree[0].children;
|
||||
// 4、根据树生成一维路由数组
|
||||
tree[0].children = linearArray(tree[0].children);
|
||||
// 5、设置完整的路由,二维路由:顶层路由 + 二级的一维路由
|
||||
tree[0].redirect = tree[0].children[0].path;
|
||||
// 6、动态添加路由
|
||||
tree.forEach((route: RouteRecordRaw) => router.addRoute(route));
|
||||
// 7、缓存一维路由
|
||||
this.routeList = tree[0].children;
|
||||
}
|
||||
}
|
||||
});
|
||||
import { defineStore } from "pinia";
|
||||
import router from "@/router/index";
|
||||
import { RouteRecordRaw } from "vue-router";
|
||||
import { getMenuListAPI } from "@/api/modules/system/index";
|
||||
import { moduleReplacement, linearArray } from "@/router/route-output";
|
||||
/**
|
||||
* 路由列表
|
||||
* @methods setRouteNames 设置路由名称集合
|
||||
* @methods setTabs 添加tabs标签页
|
||||
* @methods setCurrentRoute 设置系统内的当前路由
|
||||
* @methods removeTabsList 删除tabs页的指定路由
|
||||
* @methods removeRouteName 删除缓存路由名,用于取消页面缓存,单个删除
|
||||
* @methods removeRouteNames 删除缓存路由名,用于取消页面缓存,批量删除
|
||||
* @methods initSetRouter 路由初始化
|
||||
*/
|
||||
export const useRoutesConfigStore = defineStore("route-config", {
|
||||
state: (): any => ({
|
||||
routeTree: [], // 有访问权限的路由树
|
||||
routeList: [], // 有访问权限的一维路由数组
|
||||
cacheRoutes: [], // 所有可缓存路由的路由名
|
||||
tabsList: [], // 标签页数据
|
||||
currentRoute: {} // 当前路由
|
||||
}),
|
||||
actions: {
|
||||
/**
|
||||
* 设置可缓存路由的路由名
|
||||
* @param {string} name 路由名
|
||||
*/
|
||||
setRouteNames(name: string) {
|
||||
let state = this.cacheRoutes.some((item: string) => item === name);
|
||||
if (state) return;
|
||||
this.cacheRoutes.push(name);
|
||||
},
|
||||
/**
|
||||
* 添加tabs标签页
|
||||
* @param {object} data 当前tabs路由
|
||||
*/
|
||||
setTabs(data: Menu.MenuOptions) {
|
||||
// 当前路由在tags中是否存在,不存在则缓存
|
||||
let isExist = this.tabsList.some((item: Menu.MenuOptions) => item.name === data.name);
|
||||
if (isExist) return;
|
||||
this.tabsList.push(data);
|
||||
},
|
||||
/**
|
||||
* 设置系统内的当前路由数据
|
||||
* @param {object} data 当前路由
|
||||
*/
|
||||
setCurrentRoute(data: Menu.MenuOptions) {
|
||||
if (this.currentRoute.name && data.name === this.currentRoute.name) return;
|
||||
this.currentRoute = data;
|
||||
},
|
||||
/**
|
||||
* 删除tabs页的指定路由
|
||||
* @param {string} key 路由name
|
||||
*/
|
||||
removeTabsList(key: string) {
|
||||
const index = this.tabsList.findIndex((item: Menu.MenuOptions) => item.name === key);
|
||||
if (this.tabsList[index].meta.affix) return;
|
||||
if (index === -1) return;
|
||||
this.tabsList.splice(index, 1);
|
||||
},
|
||||
/**
|
||||
* 删除缓存路由名,用于取消页面缓存,单个删除
|
||||
* @param {string} key 路由名
|
||||
*/
|
||||
removeRouteName(key: string) {
|
||||
const index = this.cacheRoutes.findIndex((item: string) => item === key);
|
||||
if (index === -1) return;
|
||||
this.cacheRoutes.splice(index, 1);
|
||||
},
|
||||
/**
|
||||
* 删除缓存路由名,用于取消页面缓存,批量删除
|
||||
* @param {Array} list 路由名
|
||||
*/
|
||||
removeRouteNames(list: Array<string>) {
|
||||
this.cacheRoutes = this.cacheRoutes.filter((item: string) => !list.includes(item));
|
||||
},
|
||||
/**
|
||||
* 重置routeTree路由树
|
||||
*/
|
||||
async resetRoute() {
|
||||
this.routeTree = [];
|
||||
},
|
||||
/**
|
||||
* 路由初始化
|
||||
* 1、将模块设置为真实模块
|
||||
* 2、存储路由树,用于生成菜单
|
||||
* 3、根据树生成一维路由数组
|
||||
* 4、动态添加路由,设置完整的路由,二维路由:顶层路由 + 二级的一维路由
|
||||
* 5、动态添加路由
|
||||
* 6、缓存一维路由
|
||||
*/
|
||||
async initSetRouter() {
|
||||
// 1、获取过滤角色权限后的树,后端做排序处理
|
||||
let { data } = await getMenuListAPI();
|
||||
// 2、将模块设置为真实模块
|
||||
let tree = moduleReplacement(data);
|
||||
// 3、存储路由树,用于生成菜单
|
||||
this.routeTree = tree[0].children;
|
||||
// 4、根据树生成一维路由数组
|
||||
tree[0].children = linearArray(tree[0].children);
|
||||
// 5、设置完整的路由,二维路由:顶层路由 + 二级的一维路由
|
||||
tree[0].redirect = tree[0].children[0].path;
|
||||
// 6、动态添加路由
|
||||
tree.forEach((route: RouteRecordRaw) => router.addRoute(route));
|
||||
// 7、缓存一维路由
|
||||
this.routeList = tree[0].children;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -13,7 +13,7 @@ interface ThemeConfig {
|
||||
watermark: string;
|
||||
watermarkStyle: any;
|
||||
watermarkRotate: number;
|
||||
watermarkGap: Array<number>;
|
||||
watermarkGap: [number, number];
|
||||
layoutType: string;
|
||||
grayMode: Boolean;
|
||||
colorWeakMode: Boolean;
|
||||
|
||||
@ -1,29 +1,29 @@
|
||||
/**
|
||||
* 全局加载 loading-page
|
||||
* @method start 创建 loading
|
||||
* @method done 移除 loading
|
||||
*/
|
||||
export const loadingPage = {
|
||||
// 开始渲染loading
|
||||
start: () => {
|
||||
// 获取顶层body
|
||||
// 将新创建的dc-loader元素(div)插入到body元素的子元素列表中的指定位置(在指定元素之前)
|
||||
// 插入的位置是作为body元素的第一个子元素,即页面的最顶部位置
|
||||
const bodyDom: Element = document.body;
|
||||
const div = document.createElement("div");
|
||||
div.className = "loading-page";
|
||||
const loader = document.createElement("div");
|
||||
loader.className = "dc-loader";
|
||||
div.appendChild(loader);
|
||||
bodyDom.insertBefore(div, bodyDom.firstChild);
|
||||
},
|
||||
// 结束渲染loading
|
||||
done: (time: number = 0) => {
|
||||
setTimeout(() => {
|
||||
// 找到第一个匹配对象
|
||||
// 找到loading-page的父节点,移除loading-page
|
||||
const dom = document.querySelector(".loading-page");
|
||||
dom?.parentNode?.removeChild(dom);
|
||||
}, time);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 全局加载 loading-page
|
||||
* @method start 创建 loading
|
||||
* @method done 移除 loading
|
||||
*/
|
||||
export const loadingPage = {
|
||||
// 开始渲染loading
|
||||
start: () => {
|
||||
// 获取顶层body
|
||||
// 将新创建的dc-loader元素(div)插入到body元素的子元素列表中的指定位置(在指定元素之前)
|
||||
// 插入的位置是作为body元素的第一个子元素,即页面的最顶部位置
|
||||
const bodyDom: Element = document.body;
|
||||
const div = document.createElement("div");
|
||||
div.className = "loading-page";
|
||||
const loader = document.createElement("div");
|
||||
loader.className = "dc-loader";
|
||||
div.appendChild(loader);
|
||||
bodyDom.insertBefore(div, bodyDom.firstChild);
|
||||
},
|
||||
// 结束渲染loading
|
||||
done: (time: number = 0) => {
|
||||
setTimeout(() => {
|
||||
// 找到第一个匹配对象
|
||||
// 找到loading-page的父节点,移除loading-page
|
||||
const dom = document.querySelector(".loading-page");
|
||||
dom?.parentNode?.removeChild(dom);
|
||||
}, time);
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,50 +1,45 @@
|
||||
<template>
|
||||
<div class="page-404">
|
||||
<div>
|
||||
<SvgIcon name="暂无权限" :size="500" />
|
||||
</div>
|
||||
<div class="prompt">
|
||||
<div class="title">401</div>
|
||||
<div class="text">抱歉,暂无访问权限~</div>
|
||||
<a-button type="primary" @click="onBack">立即返回</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { loadingPage } from "@/utils/loading-page";
|
||||
import { useRouter } from "vue-router";
|
||||
const router = useRouter();
|
||||
const onBack = () => {
|
||||
router.go(-1);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
loadingPage.done(200);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page-404 {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
padding: $padding;
|
||||
overflow: hidden;
|
||||
.prompt {
|
||||
row-gap: $padding;
|
||||
width: 250px;
|
||||
}
|
||||
.title {
|
||||
font-size: 80px;
|
||||
color: $color-text-1;
|
||||
}
|
||||
.text {
|
||||
margin-bottom: $padding;
|
||||
font-size: $font-size-body-3;
|
||||
color: $color-text-2;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<div class="page-404">
|
||||
<div>
|
||||
<SvgIcon name="暂无权限" :size="500" />
|
||||
</div>
|
||||
<div class="prompt">
|
||||
<div class="title">401</div>
|
||||
<div class="text">抱歉,暂无访问权限~</div>
|
||||
<a-button type="primary" @click="onBack">立即返回</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useRouter } from "vue-router";
|
||||
const router = useRouter();
|
||||
const onBack = () => {
|
||||
router.go(-1);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page-404 {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
padding: $padding;
|
||||
overflow: hidden;
|
||||
.prompt {
|
||||
row-gap: $padding;
|
||||
width: 250px;
|
||||
}
|
||||
.title {
|
||||
font-size: 80px;
|
||||
color: $color-text-1;
|
||||
}
|
||||
.text {
|
||||
margin-bottom: $padding;
|
||||
font-size: $font-size-body-3;
|
||||
color: $color-text-2;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1,49 +1,45 @@
|
||||
<template>
|
||||
<div class="page-404">
|
||||
<div>
|
||||
<SvgIcon name="内容加载失败" :size="500" />
|
||||
</div>
|
||||
<div class="prompt">
|
||||
<div class="title">404</div>
|
||||
<div class="text">抱歉,访问的页面不存在~</div>
|
||||
<a-button type="primary" @click="onBack">立即返回</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { loadingPage } from "@/utils/loading-page";
|
||||
import { useRouter } from "vue-router";
|
||||
const router = useRouter();
|
||||
const onBack = () => {
|
||||
router.go(-1);
|
||||
};
|
||||
onMounted(() => {
|
||||
loadingPage.done(200);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page-404 {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
padding: $padding;
|
||||
overflow: hidden;
|
||||
.prompt {
|
||||
row-gap: $padding;
|
||||
width: 250px;
|
||||
}
|
||||
.title {
|
||||
font-size: 80px;
|
||||
color: $color-text-1;
|
||||
}
|
||||
.text {
|
||||
margin-bottom: $padding;
|
||||
font-size: $font-size-body-3;
|
||||
color: $color-text-2;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<div class="page-404">
|
||||
<div>
|
||||
<SvgIcon name="内容加载失败" :size="500" />
|
||||
</div>
|
||||
<div class="prompt">
|
||||
<div class="title">404</div>
|
||||
<div class="text">抱歉,访问的页面不存在~</div>
|
||||
<a-button type="primary" @click="onBack">立即返回</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useRouter } from "vue-router";
|
||||
const router = useRouter();
|
||||
const onBack = () => {
|
||||
router.go(-1);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page-404 {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
padding: $padding;
|
||||
overflow: hidden;
|
||||
.prompt {
|
||||
row-gap: $padding;
|
||||
width: 250px;
|
||||
}
|
||||
.title {
|
||||
font-size: 80px;
|
||||
color: $color-text-1;
|
||||
}
|
||||
.text {
|
||||
margin-bottom: $padding;
|
||||
font-size: $font-size-body-3;
|
||||
color: $color-text-2;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1,56 +1,51 @@
|
||||
<template>
|
||||
<div class="page-404">
|
||||
<div>
|
||||
<SvgIcon name="网络断开" :size="500" />
|
||||
</div>
|
||||
<div class="prompt">
|
||||
<div class="title">500</div>
|
||||
<div class="text">抱歉,无网络连接~</div>
|
||||
<a-button type="primary" v-throttle="onBack">立即返回</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { loadingPage } from "@/utils/loading-page";
|
||||
import { Message } from "@arco-design/web-vue";
|
||||
import { useRouter } from "vue-router";
|
||||
const router = useRouter();
|
||||
|
||||
const onBack = () => {
|
||||
if (!navigator.onLine) {
|
||||
Message.error("网络未连接");
|
||||
} else {
|
||||
router.go(-1);
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
loadingPage.done(200);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page-404 {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
padding: $padding;
|
||||
overflow: hidden;
|
||||
.prompt {
|
||||
row-gap: $padding;
|
||||
width: 250px;
|
||||
}
|
||||
.title {
|
||||
font-size: 80px;
|
||||
color: $color-text-1;
|
||||
}
|
||||
.text {
|
||||
margin-bottom: $padding;
|
||||
font-size: $font-size-body-3;
|
||||
color: $color-text-2;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<div class="page-404">
|
||||
<div>
|
||||
<SvgIcon name="网络断开" :size="500" />
|
||||
</div>
|
||||
<div class="prompt">
|
||||
<div class="title">500</div>
|
||||
<div class="text">抱歉,无网络连接~</div>
|
||||
<a-button type="primary" v-throttle="onBack">立即返回</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Message } from "@arco-design/web-vue";
|
||||
import { useRouter } from "vue-router";
|
||||
const router = useRouter();
|
||||
|
||||
const onBack = () => {
|
||||
if (!navigator.onLine) {
|
||||
Message.error("网络未连接");
|
||||
} else {
|
||||
router.go(-1);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page-404 {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
padding: $padding;
|
||||
overflow: hidden;
|
||||
.prompt {
|
||||
row-gap: $padding;
|
||||
width: 250px;
|
||||
}
|
||||
.title {
|
||||
font-size: 80px;
|
||||
color: $color-text-1;
|
||||
}
|
||||
.text {
|
||||
margin-bottom: $padding;
|
||||
font-size: $font-size-body-3;
|
||||
color: $color-text-2;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user