Browse Source

feat: add iframe router

一万 3 years ago
parent
commit
e3fda52801

+ 34 - 1
mock/asyncRoutes.ts

@@ -64,6 +64,38 @@ const permissionRouter = {
   ]
 };
 
+const frameRouter = {
+  path: "/iframe",
+  name: "reFrame",
+  redirect: "/iframe/pure",
+  meta: {
+    icon: "monitor",
+    title: "menus.hsExternalPage",
+    i18n: true,
+    rank: 10
+  },
+  children: [
+    {
+      path: "/frame/pure",
+      name: "reFramePure",
+      meta: {
+        i18n: true,
+        title: "menus.hsPureDocument",
+        frameSrc: "https://pure-admin-doc.vercel.app"
+      }
+    },
+    {
+      path: "/iframe/ep",
+      name: "reFrameEp",
+      meta: {
+        i18n: true,
+        title: "menus.hsEpDocument",
+        frameSrc: "https://element-plus.gitee.io/zh-CN/"
+      }
+    }
+  ]
+};
+
 const tabsRouter = {
   path: "/tabs",
   name: "reTabs",
@@ -72,7 +104,7 @@ const tabsRouter = {
     icon: "IF-team-icontabs",
     title: "menus.hstabs",
     i18n: true,
-    rank: 10
+    rank: 11
   },
   children: [
     {
@@ -113,6 +145,7 @@ export default [
           code: 0,
           info: [
             tabsRouter,
+            frameRouter,
             systemRouter,
             setDifAuthority("v-admin", permissionRouter)
           ]

+ 2 - 0
src/components/ReIcon/src/iconifyIconOffline.ts

@@ -24,6 +24,7 @@ import Location from "@iconify-icons/ep/location";
 import Tickets from "@iconify-icons/ep/tickets";
 import OfficeBuilding from "@iconify-icons/ep/office-building";
 import Notebook from "@iconify-icons/ep/notebook";
+import Monitor from "@iconify-icons/ep/monitor";
 addIcon("check", Check);
 addIcon("menu", Menu);
 addIcon("home-filled", HomeFilled);
@@ -46,6 +47,7 @@ addIcon("location", Location);
 addIcon("tickets", Tickets);
 addIcon("office-building", OfficeBuilding);
 addIcon("notebook", Notebook);
+addIcon("monitor", Monitor);
 
 // remixicon
 import arrowRightSLine from "@iconify-icons/ri/arrow-right-s-line";

+ 58 - 0
src/layout/frameView.vue

@@ -0,0 +1,58 @@
+<template>
+  <div class="frame" v-loading="loading">
+    <iframe :src="frameSrc" class="frame-iframe" ref="frameRef"></iframe>
+  </div>
+</template>
+<script lang="ts" setup>
+import { ref, unref, onMounted, nextTick } from "vue";
+import { useRoute } from "vue-router";
+
+const currentRoute = useRoute();
+const loading = ref(false);
+const frameRef = ref<HTMLElement | null>(null);
+const frameSrc = ref<string>("");
+
+if (unref(currentRoute.meta)?.frameSrc) {
+  frameSrc.value = unref(currentRoute.meta)?.frameSrc as string;
+}
+
+function hideLoading() {
+  loading.value = false;
+}
+
+function init() {
+  nextTick(() => {
+    const iframe = unref(frameRef);
+    if (!iframe) return;
+    const _frame = iframe as any;
+    if (_frame.attachEvent) {
+      _frame.attachEvent("onload", () => {
+        hideLoading();
+      });
+    } else {
+      iframe.onload = () => {
+        hideLoading();
+      };
+    }
+  });
+}
+
+onMounted(() => {
+  loading.value = true;
+  init();
+});
+</script>
+
+<style lang="scss" scoped>
+.frame {
+  height: 100vh;
+
+  &-iframe {
+    width: 100%;
+    height: 100%;
+    overflow: hidden;
+    border: 0;
+    box-sizing: border-box;
+  }
+}
+</style>

+ 4 - 1
src/plugins/i18n/en/menus.ts

@@ -36,5 +36,8 @@ export default {
   externalLink: "External Link",
   hsAble: "Able",
   hsMenuTree: "Menu Tree",
-  hsWatermark: "Water Mark"
+  hsWatermark: "Water Mark",
+  hsExternalPage: "External Page",
+  hsPureDocument: "Pure Document",
+  hsEpDocument: "Element Plus Document"
 };

+ 4 - 1
src/plugins/i18n/zh-CN/menus.ts

@@ -36,5 +36,8 @@ export default {
   externalLink: "外链",
   hsAble: "功能",
   hsMenuTree: "菜单树结构",
-  hsWatermark: "水印"
+  hsWatermark: "水印",
+  hsExternalPage: "外部页面",
+  hsPureDocument: "平台文档",
+  hsEpDocument: "Element Plus文档"
 };

+ 3 - 0
src/router/utils.ts

@@ -13,6 +13,7 @@ import { RouteConfigs } from "/@/layout/types";
 import { buildHierarchyTree } from "/@/utils/tree";
 import { usePermissionStoreHook } from "/@/store/modules/permission";
 const Layout = () => import("/@/layout/index.vue");
+const IFrame = () => import("/@/layout/frameView.vue");
 // https://cn.vitejs.dev/guide/features.html#glob-import
 const modulesRoutes = import.meta.glob("/src/views/**/*.{vue,tsx}");
 
@@ -218,6 +219,8 @@ function addAsyncRoutes(arrRoutes: Array<RouteRecordRaw>) {
   arrRoutes.forEach((v: RouteRecordRaw) => {
     if (v.redirect) {
       v.component = Layout;
+    } else if (v.meta?.frameSrc) {
+      v.component = IFrame;
     } else {
       const index = modulesRoutesKeys.findIndex(ev => ev.includes(v.path));
       v.component = modulesRoutes[modulesRoutesKeys[index]];