diff --git a/src/components/ReIcon/index.ts b/src/components/ReIcon/index.ts
index 0d2b77091..98615272c 100644
--- a/src/components/ReIcon/index.ts
+++ b/src/components/ReIcon/index.ts
@@ -13,6 +13,8 @@ export function findIconReg(icon: string) {
const faReg = /^FA-/;
// iconfont
const iFReg = /^IF-/;
+ // remixicon
+ const riReg = /^RI-/;
// typeof icon === "function" 属于SVG
if (faReg.test(icon)) {
const text = icon.split(faReg)[1];
@@ -25,12 +27,14 @@ export function findIconReg(icon: string) {
return findIcon(icon.split(iFReg)[1], "IF");
} else if (typeof icon === "function") {
return findIcon(icon, "SVG");
+ } else if (riReg.test(icon)) {
+ return findIcon(icon.split(riReg)[1], "RI");
} else {
return findIcon(icon, "EL");
}
}
-// 支持fontawesome、iconfont、element-plus/icons、自定义svg
+// 支持fontawesome、iconfont、remixicon、element-plus/icons、自定义svg
export function findIcon(icon: String, type = "EL", property?: string) {
if (type === "FA") {
return defineComponent({
@@ -49,6 +53,14 @@ export function findIcon(icon: String, type = "EL", property?: string) {
},
template: ``
});
+ } else if (type === "RI") {
+ return defineComponent({
+ name: "RIIcon",
+ data() {
+ return { icon: `ri-${icon}` };
+ },
+ template: ``
+ });
} else if (type === "EL") {
const components = iconComponents.filter(
component => component.name === icon
diff --git a/src/plugins/element-plus/index.ts b/src/plugins/element-plus/index.ts
index 4c4ac4198..60b3ae3bc 100644
--- a/src/plugins/element-plus/index.ts
+++ b/src/plugins/element-plus/index.ts
@@ -43,6 +43,7 @@ import {
ElEmpty,
ElCollapse,
ElCollapseItem,
+ ElTreeV2,
// 指令
ElLoading,
ElInfiniteScroll
@@ -94,7 +95,8 @@ const components = [
ElAvatar,
ElEmpty,
ElCollapse,
- ElCollapseItem
+ ElCollapseItem,
+ ElTreeV2
];
// https://element-plus.org/zh-CN/component/icon.html
diff --git a/src/plugins/i18n/config.ts b/src/plugins/i18n/config.ts
index 83817a509..604e7d441 100644
--- a/src/plugins/i18n/config.ts
+++ b/src/plugins/i18n/config.ts
@@ -43,6 +43,7 @@ export const menusConfig = {
permissionPage: "页面权限",
permissionButton: "按钮权限",
hstabs: "标签页操作",
+ hsMenuTree: "菜单树结构",
externalLink: "外链"
}
},
@@ -80,6 +81,7 @@ export const menusConfig = {
permissionPage: "Page Permission",
permissionButton: "Button Permission",
hstabs: "Tabs Operate",
+ hsMenuTree: "Menu Tree",
externalLink: "External Link"
}
}
diff --git a/src/router/modules/home.ts b/src/router/modules/home.ts
index 5dc5b7b3a..bb1ad2ad7 100644
--- a/src/router/modules/home.ts
+++ b/src/router/modules/home.ts
@@ -7,6 +7,7 @@ const homeRouter = {
redirect: "/welcome",
meta: {
icon: "HomeFilled",
+ title: "message.hshome",
showLink: true,
i18n: true,
rank: 0
diff --git a/src/router/modules/index.ts b/src/router/modules/index.ts
index f3658d47e..2fd1a4f79 100644
--- a/src/router/modules/index.ts
+++ b/src/router/modules/index.ts
@@ -3,6 +3,7 @@ import homeRouter from "./home";
import errorRouter from "./error";
import editorRouter from "./editor";
import nestedRouter from "./nested";
+import menuTreeRouter from "./menuTree";
import externalLink from "./externalLink";
import flowChartRouter from "./flowchart";
import remainingRouter from "./remaining";
@@ -22,6 +23,7 @@ const routes = [
nestedRouter,
externalLink,
editorRouter,
+ menuTreeRouter,
flowChartRouter,
componentsRouter
];
diff --git a/src/router/modules/menuTree.ts b/src/router/modules/menuTree.ts
new file mode 100644
index 000000000..0a16e6329
--- /dev/null
+++ b/src/router/modules/menuTree.ts
@@ -0,0 +1,29 @@
+import Layout from "/@/layout/index.vue";
+
+const menuTreeRouter = {
+ path: "/menuTree",
+ name: "reMenuTree",
+ component: Layout,
+ redirect: "/menuTree/index",
+ meta: {
+ icon: "RI-node-tree",
+ title: "message.hsMenuTree",
+ i18n: true,
+ showLink: true,
+ rank: 9
+ },
+ children: [
+ {
+ path: "/menuTree/index",
+ name: "reMenuTree",
+ component: () => import("/@/views/menu-tree/index.vue"),
+ meta: {
+ title: "message.hsMenuTree",
+ showLink: true,
+ i18n: true
+ }
+ }
+ ]
+};
+
+export default menuTreeRouter;
diff --git a/src/store/modules/permission.ts b/src/store/modules/permission.ts
index 608bc30bd..9094edf22 100644
--- a/src/store/modules/permission.ts
+++ b/src/store/modules/permission.ts
@@ -1,6 +1,7 @@
import { defineStore } from "pinia";
import { store } from "/@/store";
import { cacheType } from "./types";
+import { cloneDeep } from "lodash-es";
import { RouteConfigs } from "/@/layout/types";
import { constantMenus } from "/@/router/modules";
import { ascending, filterTree } from "/@/router/utils";
@@ -12,6 +13,8 @@ export const usePermissionStore = defineStore({
constantMenus,
// 整体路由生成的菜单(静态、动态)
wholeMenus: [],
+ // 深拷贝一个菜单树,与导航菜单不突出
+ menusTree: [],
buttonAuth: [],
// 缓存页面keepAlive
cachePageList: []
@@ -24,6 +27,10 @@ export const usePermissionStore = defineStore({
ascending(this.constantMenus.concat(routes))
);
+ this.menusTree = cloneDeep(
+ filterTree(ascending(this.constantMenus.concat(routes)))
+ );
+
const getButtonAuth = (arrRoutes: Array) => {
if (!arrRoutes || !arrRoutes.length) return;
arrRoutes.forEach((v: RouteConfigs) => {
diff --git a/src/utils/tree.ts b/src/utils/tree.ts
new file mode 100644
index 000000000..58ce86b16
--- /dev/null
+++ b/src/utils/tree.ts
@@ -0,0 +1,42 @@
+/**
+ * 提取菜单树中的每一项path
+ * @param {Object} {menuTree 菜单树}
+ * @param {return}} expandedPaths 每一项path组成的数组
+ */
+const expandedPaths = [];
+export function extractPathList(menuTree) {
+ if (!Array.isArray(menuTree)) {
+ console.warn("menuTree must be an array");
+ return;
+ }
+ if (!menuTree || menuTree.length === 0) return;
+ for (const node of menuTree) {
+ const hasChildren = node.children && node.children.length > 0;
+ if (hasChildren) {
+ extractPathList(node.children);
+ }
+ expandedPaths.push(node.path);
+ }
+ return expandedPaths;
+}
+
+/**
+ * 如果父级下children的length为1,删除children
+ * @param {Object} {menuTree 菜单树}
+ * @param {return}}
+ */
+export function deleteChildren(menuTree) {
+ if (!Array.isArray(menuTree)) {
+ console.warn("menuTree must be an array");
+ return;
+ }
+ if (!menuTree || menuTree.length === 0) return;
+ for (const node of menuTree) {
+ if (node.children && node.children.length === 1) delete node.children;
+ const hasChildren = node.children && node.children.length > 0;
+ if (hasChildren) {
+ deleteChildren(node.children);
+ }
+ }
+ return menuTree;
+}
diff --git a/src/views/menu-tree/index.vue b/src/views/menu-tree/index.vue
new file mode 100644
index 000000000..b1788ce81
--- /dev/null
+++ b/src/views/menu-tree/index.vue
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+ {{ $t(data.meta.title) }}
+
+
+