瀏覽代碼

add: 添加外链功能

xiaoxian521 3 年之前
父節點
當前提交
a8bc76ed9c

+ 3 - 4
src/components/info/index.vue

@@ -61,7 +61,7 @@ export interface ContextProps {
 
 import { useRouter, useRoute, Router } from "vue-router";
 
-import { initRouter } from "/@/router/index";
+import { initRouter } from "/@/router";
 
 export default defineComponent({
   name: "Info",
@@ -135,9 +135,8 @@ export default defineComponent({
         username: "admin",
         accessToken: "eyJhbGciOiJIUzUxMiJ9.test"
       });
-      initRouter("admin").then((router: Router) => {
-        router.push("/");
-      });
+      initRouter("admin").then((router: Router) => {});
+      router.push("/");
     };
 
     onBeforeMount(() => {

+ 1 - 1
src/layout/components/Navbar.vue

@@ -220,7 +220,7 @@ export default defineComponent({
   padding: 0 10px;
 }
 .el-dropdown-menu {
-  padding: 0;
+  padding: 6px 0;
 }
 .el-dropdown-menu__item:focus,
 .el-dropdown-menu__item:not(.is-disabled):hover {

+ 2 - 1
src/layout/components/setting/index.vue

@@ -66,7 +66,7 @@
 <script lang='ts'>
 import panel from "../panel/index.vue";
 import { onMounted, reactive, toRefs, ref, unref } from "vue";
-import { storageLocal } from "/@/utils/storage";
+import { storageLocal, storageSession } from "/@/utils/storage";
 import { toggleClass } from "/@/utils/operate";
 import { emitter } from "/@/utils/mitt";
 import { useRouter } from "vue-router";
@@ -145,6 +145,7 @@ export default {
 
     function onReset() {
       storageLocal.clear();
+      storageSession.clear();
       router.push("/login");
     }
 

+ 29 - 7
src/layout/components/sidebar/Link.vue

@@ -5,7 +5,8 @@
 </template>
 
 <script>
-import { computed, defineComponent } from "vue";
+import { computed, defineComponent, unref } from "vue"
+import { isUrl } from "/@/utils/is.ts"
 
 export default defineComponent({
   name: "Link",
@@ -16,15 +17,36 @@ export default defineComponent({
     },
   },
   setup(props) {
-    const linkProps = (to) => {
+
+    const isExternal = computed(() => {
+      return isUrl(props.to)
+    })
+
+    const type = computed(() => {
+      if (unref(isExternal)) {
+        return 'a'
+      }
+      return 'router-link'
+    })
+
+    function linkProps(to) {
+      if (unref(isExternal)) {
+        return {
+          href: to,
+          target: '_blank',
+          rel: 'noopener'
+        }
+      }
       return {
-        to: to,
-      };
-    };
+        to: to
+      }
+    }
+
     return {
-      type: "router-link",
+      isExternal,
+      type,
       linkProps,
-    };
+    }
   },
 });
 </script>

+ 16 - 2
src/layout/components/sidebar/SidebarItem.vue

@@ -42,6 +42,8 @@ import path from "path";
 import AppLink from "./Link.vue";
 import { defineComponent, PropType, ref } from "vue";
 import { RouteRecordRaw } from "vue-router";
+import { isUrl } from "/@/utils/is.ts";
+
 export default defineComponent({
   name: "SidebarItem",
   components: { AppLink },
@@ -81,15 +83,27 @@ export default defineComponent({
       }
 
       if (showingChildren.length === 0) {
+        // @ts-ignore
         onlyOneChild.value = { ...parent, path: "", noShowingChildren: true };
         return true;
       }
       return false;
     }
 
-    const resolvePath = (routePath: string) => {
+    // const resolvePath = (routePath: string) => {
+    //   return path.resolve(props.basePath, routePath);
+    // };
+
+    function resolvePath(routePath) {
+      if (isUrl(routePath)) {
+        return routePath;
+      }
+      if (isUrl(this.basePath)) {
+        return props.basePath;
+      }
+      // @ts-ignore
       return path.resolve(props.basePath, routePath);
-    };
+    }
 
     return { hasOneShowingChild, resolvePath, onlyOneChild };
   }

+ 2 - 0
src/plugins/i18n/config.ts

@@ -41,6 +41,7 @@ export const menusConfig = {
       permission: "权限管理",
       permissionPage: "页面权限",
       permissionButton: "按钮权限",
+      externalLink: "外链",
     },
   },
   en: {
@@ -76,6 +77,7 @@ export const menusConfig = {
       permission: "Permission Manage",
       permissionPage: "Page Permission",
       permissionButton: "Button Permission",
+      externalLink: "External Link",
     },
   },
 };

+ 37 - 19
src/router/index.ts

@@ -1,9 +1,4 @@
-import {
-  createRouter,
-  createWebHashHistory,
-  RouteRecordRaw,
-  Router,
-} from "vue-router";
+import { createRouter, createWebHashHistory, Router } from "vue-router";
 
 import homeRouter from "./modules/home";
 import flowChartRouter from "./modules/flowchart";
@@ -12,6 +7,7 @@ import componentsRouter from "./modules/components";
 import nestedRouter from "./modules/nested";
 import errorRouter from "./modules/error";
 import permissionRouter from "./modules/permission";
+import externalLink from "./modules/externalLink";
 import remainingRouter from "./modules/remaining"; //静态路由
 
 import { storageSession } from "../utils/storage";
@@ -20,13 +16,18 @@ import { usePermissionStoreHook } from "/@/store/modules/permission";
 
 import { getAsyncRoutes } from "/@/api/routes";
 
-const constantRoutes: Array<RouteRecordRaw> = [
+import Layout from "/@/layout/index.vue";
+// https://cn.vitejs.dev/guide/features.html#glob-import
+const modulesRoutes = import.meta.glob("/src/views/*/*/*.vue");
+
+const constantRoutes: Array<any> = [
   homeRouter,
   flowChartRouter,
   editorRouter,
   componentsRouter,
   nestedRouter,
   permissionRouter,
+  externalLink,
   errorRouter,
 ];
 
@@ -41,9 +42,6 @@ export const ascending = (arr) => {
 export const constantRoutesArr = ascending(constantRoutes).concat(
   ...remainingRouter
 );
-import Layout from "/@/layout/index.vue";
-// https://cn.vitejs.dev/guide/features.html#glob-import
-const modulesRoutes = import.meta.glob("/src/views/*/*/*.vue");
 
 // 过滤后端传来的动态路由重新生成规范路由
 export const addAsyncRoutes = (arrRoutes: Array<string>) => {
@@ -79,7 +77,7 @@ const router = createRouter({
   },
 });
 
-export const initRouter = (name) => {
+export const initRouter = (name, next?, to?) => {
   return new Promise((resolve, reject) => {
     getAsyncRoutes({ name }).then(({ info }) => {
       if (info.length === 0) {
@@ -99,6 +97,7 @@ export const initRouter = (name) => {
             // 最终路由进行升序
             ascending(router.options.routes);
             router.addRoute(v.name, v);
+            if (next && to) next({ ...to, replace: true });
             usePermissionStoreHook().changeSetting(info);
             resolve(router);
           }
@@ -112,23 +111,42 @@ export const initRouter = (name) => {
   });
 };
 
+// reset router
+export function resetRouter() {
+  router.getRoutes().forEach((route) => {
+    const { name } = route;
+    if (name) {
+      router.hasRoute(name) && router.removeRoute(name);
+    }
+  });
+}
+
 import NProgress from "../utils/progress";
 
-const whiteList = ["/login", "/register"];
+// const whiteList = ["/login", "/register"];
 
 router.beforeEach((to, _from, next) => {
   let name = storageSession.getItem("info");
-  // 刷新
-  if (name && !_from?.name) {
-    initRouter(name.username).then((router: Router) => {
-      router.push(to.path);
-    });
-  }
   NProgress.start();
   const { t } = i18n.global;
   // @ts-ignore
   to.meta.title ? (document.title = t(to.meta.title)) : ""; // 动态title
-  whiteList.indexOf(to.path) !== -1 || name ? next() : next("/login"); // 全部重定向到登录页
+  if (name) {
+    if (_from?.name) {
+      next();
+    } else {
+      initRouter(name.username, next, to).then((router: Router) => {
+        router.push(to.path);
+      });
+      next();
+    }
+  } else {
+    if (to.path !== "/login") {
+      next({ path: "/login" });
+    } else {
+      next();
+    }
+  }
 });
 
 router.afterEach(() => {

+ 28 - 0
src/router/modules/externalLink.ts

@@ -0,0 +1,28 @@
+import Layout from "/@/layout/index.vue";
+
+const externalLink = {
+  path: "/external",
+  name: "external",
+  component: Layout,
+  meta: {
+    icon: "el-icon-link",
+    title: "message.externalLink",
+    showLink: true,
+    savedPosition: true,
+    rank: 190,
+  },
+  children: [
+    {
+      path: "https://github.com/xiaoxian521/vue-pure-admin",
+      meta: {
+        icon: "el-icon-link",
+        title: "message.externalLink",
+        showLink: true,
+        savedPosition: true,
+        rank: 191,
+      },
+    },
+  ],
+};
+
+export default externalLink;