mirror of
				https://github.com/pure-admin/vue-pure-admin.git
				synced 2025-11-03 13:44:47 +08:00 
			
		
		
		
	add: 添加外链功能
This commit is contained in:
		
							parent
							
								
									6b36c93779
								
							
						
					
					
						commit
						a8bc76ed9c
					
				@ -61,7 +61,7 @@ export interface ContextProps {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import { useRouter, useRoute, Router } from "vue-router";
 | 
					import { useRouter, useRoute, Router } from "vue-router";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { initRouter } from "/@/router/index";
 | 
					import { initRouter } from "/@/router";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default defineComponent({
 | 
					export default defineComponent({
 | 
				
			||||||
  name: "Info",
 | 
					  name: "Info",
 | 
				
			||||||
@ -135,9 +135,8 @@ export default defineComponent({
 | 
				
			|||||||
        username: "admin",
 | 
					        username: "admin",
 | 
				
			||||||
        accessToken: "eyJhbGciOiJIUzUxMiJ9.test"
 | 
					        accessToken: "eyJhbGciOiJIUzUxMiJ9.test"
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
      initRouter("admin").then((router: Router) => {
 | 
					      initRouter("admin").then((router: Router) => {});
 | 
				
			||||||
        router.push("/");
 | 
					      router.push("/");
 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    onBeforeMount(() => {
 | 
					    onBeforeMount(() => {
 | 
				
			||||||
 | 
				
			|||||||
@ -220,7 +220,7 @@ export default defineComponent({
 | 
				
			|||||||
  padding: 0 10px;
 | 
					  padding: 0 10px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
.el-dropdown-menu {
 | 
					.el-dropdown-menu {
 | 
				
			||||||
  padding: 0;
 | 
					  padding: 6px 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
.el-dropdown-menu__item:focus,
 | 
					.el-dropdown-menu__item:focus,
 | 
				
			||||||
.el-dropdown-menu__item:not(.is-disabled):hover {
 | 
					.el-dropdown-menu__item:not(.is-disabled):hover {
 | 
				
			||||||
 | 
				
			|||||||
@ -66,7 +66,7 @@
 | 
				
			|||||||
<script lang='ts'>
 | 
					<script lang='ts'>
 | 
				
			||||||
import panel from "../panel/index.vue";
 | 
					import panel from "../panel/index.vue";
 | 
				
			||||||
import { onMounted, reactive, toRefs, ref, unref } from "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 { toggleClass } from "/@/utils/operate";
 | 
				
			||||||
import { emitter } from "/@/utils/mitt";
 | 
					import { emitter } from "/@/utils/mitt";
 | 
				
			||||||
import { useRouter } from "vue-router";
 | 
					import { useRouter } from "vue-router";
 | 
				
			||||||
@ -145,6 +145,7 @@ export default {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    function onReset() {
 | 
					    function onReset() {
 | 
				
			||||||
      storageLocal.clear();
 | 
					      storageLocal.clear();
 | 
				
			||||||
 | 
					      storageSession.clear();
 | 
				
			||||||
      router.push("/login");
 | 
					      router.push("/login");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -5,7 +5,8 @@
 | 
				
			|||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script>
 | 
					<script>
 | 
				
			||||||
import { computed, defineComponent } from "vue";
 | 
					import { computed, defineComponent, unref } from "vue"
 | 
				
			||||||
 | 
					import { isUrl } from "/@/utils/is.ts"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default defineComponent({
 | 
					export default defineComponent({
 | 
				
			||||||
  name: "Link",
 | 
					  name: "Link",
 | 
				
			||||||
@ -16,15 +17,36 @@ export default defineComponent({
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  setup(props) {
 | 
					  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 {
 | 
					      return {
 | 
				
			||||||
        to: to,
 | 
					        to: to
 | 
				
			||||||
      };
 | 
					      }
 | 
				
			||||||
    };
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
      type: "router-link",
 | 
					      isExternal,
 | 
				
			||||||
 | 
					      type,
 | 
				
			||||||
      linkProps,
 | 
					      linkProps,
 | 
				
			||||||
    };
 | 
					    }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
				
			|||||||
@ -42,6 +42,8 @@ import path from "path";
 | 
				
			|||||||
import AppLink from "./Link.vue";
 | 
					import AppLink from "./Link.vue";
 | 
				
			||||||
import { defineComponent, PropType, ref } from "vue";
 | 
					import { defineComponent, PropType, ref } from "vue";
 | 
				
			||||||
import { RouteRecordRaw } from "vue-router";
 | 
					import { RouteRecordRaw } from "vue-router";
 | 
				
			||||||
 | 
					import { isUrl } from "/@/utils/is.ts";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default defineComponent({
 | 
					export default defineComponent({
 | 
				
			||||||
  name: "SidebarItem",
 | 
					  name: "SidebarItem",
 | 
				
			||||||
  components: { AppLink },
 | 
					  components: { AppLink },
 | 
				
			||||||
@ -81,15 +83,27 @@ export default defineComponent({
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (showingChildren.length === 0) {
 | 
					      if (showingChildren.length === 0) {
 | 
				
			||||||
 | 
					        // @ts-ignore
 | 
				
			||||||
        onlyOneChild.value = { ...parent, path: "", noShowingChildren: true };
 | 
					        onlyOneChild.value = { ...parent, path: "", noShowingChildren: true };
 | 
				
			||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      return false;
 | 
					      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 path.resolve(props.basePath, routePath);
 | 
				
			||||||
    };
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return { hasOneShowingChild, resolvePath, onlyOneChild };
 | 
					    return { hasOneShowingChild, resolvePath, onlyOneChild };
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
@ -41,6 +41,7 @@ export const menusConfig = {
 | 
				
			|||||||
      permission: "权限管理",
 | 
					      permission: "权限管理",
 | 
				
			||||||
      permissionPage: "页面权限",
 | 
					      permissionPage: "页面权限",
 | 
				
			||||||
      permissionButton: "按钮权限",
 | 
					      permissionButton: "按钮权限",
 | 
				
			||||||
 | 
					      externalLink: "外链",
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  en: {
 | 
					  en: {
 | 
				
			||||||
@ -76,6 +77,7 @@ export const menusConfig = {
 | 
				
			|||||||
      permission: "Permission Manage",
 | 
					      permission: "Permission Manage",
 | 
				
			||||||
      permissionPage: "Page Permission",
 | 
					      permissionPage: "Page Permission",
 | 
				
			||||||
      permissionButton: "Button Permission",
 | 
					      permissionButton: "Button Permission",
 | 
				
			||||||
 | 
					      externalLink: "External Link",
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -1,9 +1,4 @@
 | 
				
			|||||||
import {
 | 
					import { createRouter, createWebHashHistory, Router } from "vue-router";
 | 
				
			||||||
  createRouter,
 | 
					 | 
				
			||||||
  createWebHashHistory,
 | 
					 | 
				
			||||||
  RouteRecordRaw,
 | 
					 | 
				
			||||||
  Router,
 | 
					 | 
				
			||||||
} from "vue-router";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import homeRouter from "./modules/home";
 | 
					import homeRouter from "./modules/home";
 | 
				
			||||||
import flowChartRouter from "./modules/flowchart";
 | 
					import flowChartRouter from "./modules/flowchart";
 | 
				
			||||||
@ -12,6 +7,7 @@ import componentsRouter from "./modules/components";
 | 
				
			|||||||
import nestedRouter from "./modules/nested";
 | 
					import nestedRouter from "./modules/nested";
 | 
				
			||||||
import errorRouter from "./modules/error";
 | 
					import errorRouter from "./modules/error";
 | 
				
			||||||
import permissionRouter from "./modules/permission";
 | 
					import permissionRouter from "./modules/permission";
 | 
				
			||||||
 | 
					import externalLink from "./modules/externalLink";
 | 
				
			||||||
import remainingRouter from "./modules/remaining"; //静态路由
 | 
					import remainingRouter from "./modules/remaining"; //静态路由
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { storageSession } from "../utils/storage";
 | 
					import { storageSession } from "../utils/storage";
 | 
				
			||||||
@ -20,13 +16,18 @@ import { usePermissionStoreHook } from "/@/store/modules/permission";
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import { getAsyncRoutes } from "/@/api/routes";
 | 
					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,
 | 
					  homeRouter,
 | 
				
			||||||
  flowChartRouter,
 | 
					  flowChartRouter,
 | 
				
			||||||
  editorRouter,
 | 
					  editorRouter,
 | 
				
			||||||
  componentsRouter,
 | 
					  componentsRouter,
 | 
				
			||||||
  nestedRouter,
 | 
					  nestedRouter,
 | 
				
			||||||
  permissionRouter,
 | 
					  permissionRouter,
 | 
				
			||||||
 | 
					  externalLink,
 | 
				
			||||||
  errorRouter,
 | 
					  errorRouter,
 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -41,9 +42,6 @@ export const ascending = (arr) => {
 | 
				
			|||||||
export const constantRoutesArr = ascending(constantRoutes).concat(
 | 
					export const constantRoutesArr = ascending(constantRoutes).concat(
 | 
				
			||||||
  ...remainingRouter
 | 
					  ...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>) => {
 | 
					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) => {
 | 
					  return new Promise((resolve, reject) => {
 | 
				
			||||||
    getAsyncRoutes({ name }).then(({ info }) => {
 | 
					    getAsyncRoutes({ name }).then(({ info }) => {
 | 
				
			||||||
      if (info.length === 0) {
 | 
					      if (info.length === 0) {
 | 
				
			||||||
@ -99,6 +97,7 @@ export const initRouter = (name) => {
 | 
				
			|||||||
            // 最终路由进行升序
 | 
					            // 最终路由进行升序
 | 
				
			||||||
            ascending(router.options.routes);
 | 
					            ascending(router.options.routes);
 | 
				
			||||||
            router.addRoute(v.name, v);
 | 
					            router.addRoute(v.name, v);
 | 
				
			||||||
 | 
					            if (next && to) next({ ...to, replace: true });
 | 
				
			||||||
            usePermissionStoreHook().changeSetting(info);
 | 
					            usePermissionStoreHook().changeSetting(info);
 | 
				
			||||||
            resolve(router);
 | 
					            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";
 | 
					import NProgress from "../utils/progress";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const whiteList = ["/login", "/register"];
 | 
					// const whiteList = ["/login", "/register"];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
router.beforeEach((to, _from, next) => {
 | 
					router.beforeEach((to, _from, next) => {
 | 
				
			||||||
  let name = storageSession.getItem("info");
 | 
					  let name = storageSession.getItem("info");
 | 
				
			||||||
  // 刷新
 | 
					 | 
				
			||||||
  if (name && !_from?.name) {
 | 
					 | 
				
			||||||
    initRouter(name.username).then((router: Router) => {
 | 
					 | 
				
			||||||
      router.push(to.path);
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  NProgress.start();
 | 
					  NProgress.start();
 | 
				
			||||||
  const { t } = i18n.global;
 | 
					  const { t } = i18n.global;
 | 
				
			||||||
  // @ts-ignore
 | 
					  // @ts-ignore
 | 
				
			||||||
  to.meta.title ? (document.title = t(to.meta.title)) : ""; // 动态title
 | 
					  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(() => {
 | 
					router.afterEach(() => {
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										28
									
								
								src/router/modules/externalLink.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/router/modules/externalLink.ts
									
									
									
									
									
										Normal file
									
								
							@ -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;
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user