feat: 外链的处理逻辑以及全局视口组件封装

This commit is contained in:
wang_fan_w 2024-06-28 19:01:54 +08:00
parent 7305de45a0
commit 3ae0c6ed19
14 changed files with 149 additions and 28 deletions

View File

@ -2,8 +2,7 @@
### 介绍 📖
DC-Admin 一款基于 Vue3、TypeScript、Vite5、Pinia、Arco-Design 开源的后台管理框架使用目前最新技术栈开发。项目提供了一些常用组件在一定程度上提高您的开发效率。另外本项目还封装了一些常用组件、Hooks、动态路由等功能。
DC-Admin 一款基于 Vue3、TypeScript、Vite5、Pinia、Arco-Design 开源的后台管理框架符合直觉的使用模式使用目前最新技术栈开发。项目提供了一些常用组件在一定程度上提高您的开发效率。另外本项目还封装了一些常用组件、Hooks、动态路由等功能。
### 在线预览 👀
@ -75,29 +74,18 @@ pnpm lint:eslint
pnpm lint:prettier
```
### 项目截图 📷
- 登录页:
- 首页:
- 表格页:
- 用户中心:
- 系统配置页:
### 文件资源目录 📚
```text
@ -153,4 +141,4 @@ DC-Admin
### 项目后台接口 🧩
建设中
建设中

2
src/components.d.ts vendored
View File

@ -9,6 +9,8 @@ declare module 'vue' {
export interface GlobalComponents {
CodemirrorCode: typeof import('./components/codemirror-code/index.vue')['default']
CodeView: typeof import('./components/code-view/index.vue')['default']
ExternalLinkPage: typeof import('./components/external-link-page/index.vue')['default']
FillPage: typeof import('./components/fill-page/index.vue')['default']
LangProvider: typeof import('./components/lang-provider/index.vue')['default']
MainTransition: typeof import('./components/main-transition/index.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink']

View File

@ -0,0 +1,42 @@
<template>
<FillPage>
<div class="external-link-page">
<div>
<div class="star-emoji">🌍</div>
<div class="docs-text">外链页面已经在新窗口中打开</div>
<div class="to-page"><a-button type="primary" @click="openPage">立即前往</a-button></div>
</div>
</div>
</FillPage>
</template>
<script setup lang="ts">
import { useRoute } from "vue-router";
const route = useRoute();
const openPage = () => {
window.open(route.meta.link as string, "_blank");
};
</script>
<style lang="scss" scoped>
.external-link-page {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
.star-emoji {
text-align: center;
font-size: 100px;
}
.docs-text {
text-align: center;
color: $color-text-3;
margin: $margin 0;
}
.to-page {
text-align: center;
display: flex;
justify-content: center;
}
}
</style>

View File

@ -0,0 +1,48 @@
<template>
<div
class="fill-page-size"
:style="{
height: viewportHeight
}"
>
<div class="fill-page-inner">
<slot></slot>
</div>
</div>
</template>
<script setup lang="ts">
import { storeToRefs } from "pinia";
import { useThemeConfig } from "@/store/modules/theme-config";
const themeStore = useThemeConfig();
let { isTabs, isFooter } = storeToRefs(themeStore);
// footer: 30px
// tabs: 40px
// head: 60px
const viewportHeight = computed(() => {
// tabsfooter
if (isTabs.value && isFooter.value) {
return `calc(100vh - 60px - 30px - 40px)`;
} else if (!isTabs.value && isFooter.value) {
// tabsfooter
return `calc(100vh - 60px - 30px)`;
} else {
// tabsfooterhead
return `calc(100vh - 60px)`;
}
});
</script>
<style lang="scss" scoped>
.fill-page-size {
padding: $padding;
box-sizing: border-box;
}
.fill-page-inner {
height: 100%;
box-sizing: border-box;
padding: $padding;
background: $color-bg-1;
overflow: hidden;
}
</style>

View File

@ -27,8 +27,21 @@ export const useRoutingMethod = () => {
const { tabsList } = storeToRefs(routerStore);
return tabsList.value.find((item: Menu.MenuOptions) => item.name == key);
};
/**
* url跳转
* @param {any} route
*/
const openExternalLinks = (route: any) => {
// 处理外链跳转
if (route.meta.link && !route.meta.iframe) {
window.open(route.meta.link as string, "_blank");
}
};
return {
findLinearArray,
findTagsList
findTagsList,
openExternalLinks
};
};

View File

@ -25,6 +25,7 @@ export default {
["user-settings"]: "user settings",
["external-links"]: "external links",
["link-gitee"]: "link gitee",
["link-juejin"]: "link juejin",
["about-project"]: "about project",
["not-power"]: "No permission",
["not-found"]: "Page not found",

View File

@ -25,7 +25,8 @@ export default {
["user-settings"]: "用户设置",
["about-project"]: "关于项目",
["external-links"]: "外部链接",
["link-gitee"]: "链接 gitee",
["link-gitee"]: "外链 gitee",
["link-juejin"]: "外链 掘金",
["not-power"]: "没有权限",
["not-found"]: "未找到页面",
["zh-CN"]: "中文",

View File

@ -1,6 +1,6 @@
<template>
<a-watermark :content="watermark" v-bind="watermarkConfig">
<a-layout-content :class="isFooter ? 'content' : 'content-no-footer'">
<a-layout-content :class="isFooter ? 'layout-main-content' : 'layout-main-content-no-footer'">
<Tabs v-if="isTabs" />
<a-scrollbar style="height: 100%; overflow: auto" :outer-class="isTabs ? 'scrollbar' : 'scrollbar-no-tabs'">
<div>
@ -42,10 +42,10 @@ watch(watermarkConfig, newv => {
</script>
<style lang="scss" scoped>
.content {
.layout-main-content {
height: calc(100vh - 60px - 30px); // -headerfooter
}
.content-no-footer {
.layout-main-content-no-footer {
height: calc(100vh - 60px); // -footer
}

View File

@ -6,6 +6,7 @@ import { initSetRouter, currentlyRoute } from "@/router/route-output";
import { storeToRefs } from "pinia";
import { useUserInfoStore } from "@/store/modules/user-info";
import { useRoutesListStore } from "@/store/modules/route-list";
import { useRoutingMethod } from "@/hooks/useRoutingMethod";
/**
* vue的路由示例
@ -55,13 +56,23 @@ router.beforeEach(async (to, from, next) => {
// 4、去非登录页有token校验是否动态添加过路由添加过则放行未添加则执行路由初始化
const routeStore = useRoutesListStore(pinia);
const { routeTree } = storeToRefs(routeStore);
// 获取外链路由的处理函数
// 所有的路由正常放行,只不过额外判断是否是外链,如果是,则打开新窗口跳转外链
// 外链的页面依旧正常打开只不过不会参与缓存与tabs显示符合路由跳转的直觉
const { openExternalLinks } = useRoutingMethod();
// 如果缓存的路由是0则说明未动态添加路由先添加再跳转
// 解决刷新页面404的问题
if (routeTree.value.length == 0) {
await initSetRouter();
// 处理外链跳转
openExternalLinks(to);
// 处理完重新跳转
next({ path: to.path, query: to.query });
} else {
// 处理外链跳转
openExternalLinks(to);
// 动态路由添加过走这里,直接放行
next();
// 项目内的跳转,处理跳转路由高亮

View File

@ -104,9 +104,10 @@ export const currentlyRoute = (name: string) => {
// 存入当前路由-高亮
store.setCurrentRoute(find);
// 如果是外链路由则不做后续任何缓存操作: 有外链 && 内嵌false
// 如果是外链路由则不做后续任何缓存操作,条件: 有外链 && 内嵌
if (find.meta.link && !find.meta.iframe) return;
// 存入tabs栏数据开启tabs
// 存入tabs栏数据条件开启tabs
if (isTabs.value) store.setTabs(find);
// 不缓存路由 || 不渲染tabs ,符合任意条件则不缓存路由
if (!find.meta.keepAlive || !isTabs.value) return;

View File

@ -318,6 +318,22 @@ export const dynamicRoutes: RouteRecordRaw[] = [
icon: "icon-menu"
},
children: []
},
{
path: "/external-links/link-juejin",
name: "link-juejin",
component: () => import("@/views/external-links/link-juejin/link-juejin.vue"),
meta: {
title: "link-juejin",
hide: false,
keepAlive: true,
affix: false,
link: "https://juejin.cn/user/1728883023940600", // 链接
iframe: false, // 区分是否内链 true内链 false外链
roles: ["admin"],
icon: "icon-menu"
},
children: []
}
]
},

View File

@ -1,5 +1,6 @@
/* global style scss */
.dc-page {
// margin padding 边距一致是为了保持视觉上的内外统一
margin: $padding;
padding: $padding;
background: $color-bg-1;

View File

@ -1,9 +1,3 @@
<template>
<div>外部链接 gitee <a-date-picker v-model="form" placeholder="请选择日期" /></div>
<ExternalLinkPage />
</template>
<script setup lang="ts">
const form = ref();
</script>
<style lang="scss" scoped></style>

View File

@ -0,0 +1,3 @@
<template>
<ExternalLinkPage />
</template>