mirror of
https://github.com/pure-admin/vue-pure-admin.git
synced 2025-11-09 13:53:38 +08:00
perf: 更完善的全局类型提示
This commit is contained in:
@@ -3,9 +3,9 @@ import { useRouter } from "vue-router";
|
||||
import { cloneDeep } from "lodash-unified";
|
||||
import SearchResult from "./SearchResult.vue";
|
||||
import SearchFooter from "./SearchFooter.vue";
|
||||
import { deleteChildren } from "@/utils/tree";
|
||||
import { useNav } from "@/layout/hooks/useNav";
|
||||
import { transformI18n } from "@/plugins/i18n";
|
||||
import { deleteChildren } from "@pureadmin/utils";
|
||||
import { useDebounceFn, onKeyStroke } from "@vueuse/core";
|
||||
import { ref, watch, computed, nextTick, shallowRef } from "vue";
|
||||
import { usePermissionStoreHook } from "@/store/modules/permission";
|
||||
|
||||
@@ -4,7 +4,6 @@ import { useRoute } from "vue-router";
|
||||
import { emitter } from "@/utils/mitt";
|
||||
import SidebarItem from "./sidebarItem.vue";
|
||||
import leftCollapse from "./leftCollapse.vue";
|
||||
import type { StorageConfigs } from "/#/index";
|
||||
import { useNav } from "@/layout/hooks/useNav";
|
||||
import { storageLocal } from "@pureadmin/utils";
|
||||
import { ref, computed, watch, onBeforeMount } from "vue";
|
||||
|
||||
@@ -9,7 +9,6 @@ import {
|
||||
getCurrentInstance
|
||||
} from "vue";
|
||||
import { tagsViewsType } from "../types";
|
||||
import type { StorageConfigs } from "/#/index";
|
||||
import { useEventListener } from "@vueuse/core";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import { transformI18n, $t } from "@/plugins/i18n";
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// 多组件库的国际化和本地项目国际化兼容
|
||||
import { App, WritableComputedRef } from "vue";
|
||||
import type { StorageConfigs } from "/#/index";
|
||||
import { storageLocal } from "@pureadmin/utils";
|
||||
import { type I18n, createI18n } from "vue-i18n";
|
||||
|
||||
|
||||
47
src/router/enums.ts
Normal file
47
src/router/enums.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
// 完整版菜单比较多,将 rank 抽离出来,在此方便维护
|
||||
|
||||
const home = 0, // 平台规定只有 home 路由的 rank 才能为 0 ,所以后端在返回 rank 的时候需要从 1 开始哦
|
||||
doc = 1,
|
||||
utils = 2,
|
||||
table = 3,
|
||||
tree = 4,
|
||||
able = 5,
|
||||
components = 6,
|
||||
frame = 7,
|
||||
nested = 8,
|
||||
result = 9,
|
||||
error = 10,
|
||||
list = 11,
|
||||
permission = 12,
|
||||
system = 13,
|
||||
tabs = 14,
|
||||
formdesign = 15,
|
||||
flowchart = 16,
|
||||
ppt = 17,
|
||||
editor = 18,
|
||||
guide = 19,
|
||||
about = 20;
|
||||
|
||||
export {
|
||||
home,
|
||||
doc,
|
||||
utils,
|
||||
table,
|
||||
tree,
|
||||
able,
|
||||
components,
|
||||
frame,
|
||||
nested,
|
||||
result,
|
||||
error,
|
||||
list,
|
||||
permission,
|
||||
system,
|
||||
tabs,
|
||||
formdesign,
|
||||
flowchart,
|
||||
ppt,
|
||||
editor,
|
||||
guide,
|
||||
about
|
||||
};
|
||||
@@ -1,6 +1,5 @@
|
||||
import "@/utils/sso";
|
||||
import { getConfig } from "@/config";
|
||||
import { toRouteType } from "./types";
|
||||
import NProgress from "@/utils/progress";
|
||||
import { findIndex } from "lodash-unified";
|
||||
import { transformI18n } from "@/plugins/i18n";
|
||||
@@ -23,12 +22,9 @@ import {
|
||||
formatTwoStageRoutes,
|
||||
formatFlatteningRoutes
|
||||
} from "./utils";
|
||||
import {
|
||||
isUrl,
|
||||
openLink,
|
||||
storageSession,
|
||||
buildHierarchyTree
|
||||
} from "@pureadmin/utils";
|
||||
import { buildHierarchyTree } from "@/utils/tree";
|
||||
import { isUrl, openLink, storageSession } from "@pureadmin/utils";
|
||||
|
||||
import remainingRouter from "./modules/remaining";
|
||||
|
||||
/** 自动导入全部静态路由,无需再手动引入!匹配 src/router/modules 目录(任何嵌套级别)中具有 .ts 扩展名的所有文件,除了 remaining.ts 文件
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { $t } from "@/plugins/i18n";
|
||||
import type { RouteConfigsTable } from "/#/index";
|
||||
import { able } from "@/router/enums";
|
||||
|
||||
const ableRouter: RouteConfigsTable = {
|
||||
export default {
|
||||
path: "/able",
|
||||
redirect: "/able/watermark",
|
||||
meta: {
|
||||
icon: "ubuntu-fill",
|
||||
title: $t("menus.hsAble"),
|
||||
rank: 5
|
||||
rank: able
|
||||
},
|
||||
children: [
|
||||
{
|
||||
@@ -163,6 +163,4 @@ const ableRouter: RouteConfigsTable = {
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
export default ableRouter;
|
||||
} as RouteConfigsTable;
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { $t } from "@/plugins/i18n";
|
||||
import type { RouteConfigsTable } from "/#/index";
|
||||
import { about } from "@/router/enums";
|
||||
|
||||
const aboutRouter: RouteConfigsTable = {
|
||||
export default {
|
||||
path: "/about",
|
||||
redirect: "/about/index",
|
||||
meta: {
|
||||
// icon: "question-line",
|
||||
title: $t("menus.hsAbout"),
|
||||
rank: 15
|
||||
rank: about
|
||||
},
|
||||
children: [
|
||||
{
|
||||
@@ -19,6 +19,4 @@ const aboutRouter: RouteConfigsTable = {
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
export default aboutRouter;
|
||||
} as RouteConfigsTable;
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { $t } from "@/plugins/i18n";
|
||||
import type { RouteConfigsTable } from "/#/index";
|
||||
import { components } from "@/router/enums";
|
||||
|
||||
const componentsRouter: RouteConfigsTable = {
|
||||
export default {
|
||||
path: "/components",
|
||||
redirect: "/components/video",
|
||||
meta: {
|
||||
icon: "menu",
|
||||
title: $t("menus.hscomponents"),
|
||||
rank: 6
|
||||
rank: components
|
||||
},
|
||||
children: [
|
||||
{
|
||||
@@ -127,6 +127,4 @@ const componentsRouter: RouteConfigsTable = {
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
export default componentsRouter;
|
||||
} as RouteConfigsTable;
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { $t } from "@/plugins/i18n";
|
||||
import type { RouteConfigsTable } from "/#/index";
|
||||
import { editor } from "@/router/enums";
|
||||
|
||||
const editorRouter: RouteConfigsTable = {
|
||||
export default {
|
||||
path: "/editor",
|
||||
redirect: "/editor/index",
|
||||
meta: {
|
||||
icon: "edit",
|
||||
title: $t("menus.hseditor"),
|
||||
rank: 2
|
||||
rank: editor
|
||||
},
|
||||
children: [
|
||||
{
|
||||
@@ -20,6 +20,4 @@ const editorRouter: RouteConfigsTable = {
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
export default editorRouter;
|
||||
} as RouteConfigsTable;
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { $t } from "@/plugins/i18n";
|
||||
import type { RouteConfigsTable } from "/#/index";
|
||||
import { error } from "@/router/enums";
|
||||
|
||||
const errorRouter: RouteConfigsTable = {
|
||||
export default {
|
||||
path: "/error",
|
||||
redirect: "/error/403",
|
||||
meta: {
|
||||
icon: "information-line",
|
||||
title: $t("menus.hsabnormal"),
|
||||
rank: 9
|
||||
rank: error
|
||||
},
|
||||
children: [
|
||||
{
|
||||
@@ -35,6 +35,4 @@ const errorRouter: RouteConfigsTable = {
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
export default errorRouter;
|
||||
} as RouteConfigsTable;
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { $t } from "@/plugins/i18n";
|
||||
import type { RouteConfigsTable } from "/#/index";
|
||||
import { flowchart } from "@/router/enums";
|
||||
|
||||
const flowChartRouter: RouteConfigsTable = {
|
||||
export default {
|
||||
path: "/flowChart",
|
||||
redirect: "/flowChart/index",
|
||||
meta: {
|
||||
icon: "set-up",
|
||||
title: $t("menus.hsflowChart"),
|
||||
rank: 1
|
||||
rank: flowchart
|
||||
},
|
||||
children: [
|
||||
{
|
||||
@@ -19,6 +19,4 @@ const flowChartRouter: RouteConfigsTable = {
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
export default flowChartRouter;
|
||||
} as RouteConfigsTable;
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { $t } from "@/plugins/i18n";
|
||||
import type { RouteConfigsTable } from "/#/index";
|
||||
import { formdesign } from "@/router/enums";
|
||||
const IFrame = () => import("@/layout/frameView.vue");
|
||||
|
||||
const formDesignRouter: RouteConfigsTable = {
|
||||
export default {
|
||||
path: "/formDesign",
|
||||
redirect: "/formDesign/index",
|
||||
meta: {
|
||||
icon: "terminal-window-line",
|
||||
title: $t("menus.hsFormDesign"),
|
||||
rank: 2
|
||||
rank: formdesign
|
||||
},
|
||||
children: [
|
||||
{
|
||||
@@ -22,6 +22,4 @@ const formDesignRouter: RouteConfigsTable = {
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
export default formDesignRouter;
|
||||
} as RouteConfigsTable;
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { $t } from "@/plugins/i18n";
|
||||
import type { RouteConfigsTable } from "/#/index";
|
||||
import { guide } from "@/router/enums";
|
||||
|
||||
const guideRouter: RouteConfigsTable = {
|
||||
export default {
|
||||
path: "/guide",
|
||||
redirect: "/guide/index",
|
||||
meta: {
|
||||
icon: "guide",
|
||||
title: $t("menus.hsguide"),
|
||||
rank: 14
|
||||
rank: guide
|
||||
},
|
||||
children: [
|
||||
{
|
||||
@@ -19,6 +19,4 @@ const guideRouter: RouteConfigsTable = {
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
export default guideRouter;
|
||||
} as RouteConfigsTable;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { $t } from "@/plugins/i18n";
|
||||
import type { RouteConfigsTable } from "/#/index";
|
||||
import { home } from "@/router/enums";
|
||||
const Layout = () => import("@/layout/index.vue");
|
||||
|
||||
const homeRouter: RouteConfigsTable = {
|
||||
export default {
|
||||
path: "/",
|
||||
name: "Home",
|
||||
component: Layout,
|
||||
@@ -10,7 +10,7 @@ const homeRouter: RouteConfigsTable = {
|
||||
meta: {
|
||||
icon: "home-filled",
|
||||
title: $t("menus.hshome"),
|
||||
rank: 0
|
||||
rank: home
|
||||
},
|
||||
children: [
|
||||
{
|
||||
@@ -22,6 +22,4 @@ const homeRouter: RouteConfigsTable = {
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
export default homeRouter;
|
||||
} as RouteConfigsTable;
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { $t } from "@/plugins/i18n";
|
||||
import type { RouteConfigsTable } from "/#/index";
|
||||
import { list } from "@/router/enums";
|
||||
|
||||
const ableRouter: RouteConfigsTable = {
|
||||
export default {
|
||||
path: "/list",
|
||||
redirect: "/list/card",
|
||||
meta: {
|
||||
icon: "list-check",
|
||||
title: $t("menus.hsList"),
|
||||
rank: 12
|
||||
rank: list
|
||||
},
|
||||
children: [
|
||||
{
|
||||
@@ -21,6 +21,4 @@ const ableRouter: RouteConfigsTable = {
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
export default ableRouter;
|
||||
} as RouteConfigsTable;
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { $t } from "@/plugins/i18n";
|
||||
import type { RouteConfigsTable } from "/#/index";
|
||||
import { nested } from "@/router/enums";
|
||||
|
||||
const nestedRouter: RouteConfigsTable = {
|
||||
export default {
|
||||
path: "/nested",
|
||||
redirect: "/nested/menu1/menu1-1",
|
||||
meta: {
|
||||
title: $t("menus.hsmenus"),
|
||||
icon: "histogram",
|
||||
rank: 7
|
||||
rank: nested
|
||||
},
|
||||
children: [
|
||||
{
|
||||
@@ -82,6 +82,4 @@ const nestedRouter: RouteConfigsTable = {
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
export default nestedRouter;
|
||||
} as RouteConfigsTable;
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import type { RouteConfigsTable } from "/#/index";
|
||||
import { ppt } from "@/router/enums";
|
||||
const IFrame = () => import("@/layout/frameView.vue");
|
||||
|
||||
const pptRouter: RouteConfigsTable = {
|
||||
export default {
|
||||
path: "/ppt",
|
||||
redirect: "/ppt/index",
|
||||
meta: {
|
||||
icon: "ppt",
|
||||
title: "PPT",
|
||||
rank: 3
|
||||
rank: ppt
|
||||
},
|
||||
children: [
|
||||
{
|
||||
@@ -21,6 +21,4 @@ const pptRouter: RouteConfigsTable = {
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
export default pptRouter;
|
||||
} as RouteConfigsTable;
|
||||
|
||||
24
src/router/modules/puredoc.ts
Normal file
24
src/router/modules/puredoc.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { doc } from "@/router/enums";
|
||||
import hot from "@/assets/svg/hot.svg?component";
|
||||
const IFrame = () => import("@/layout/frameView.vue");
|
||||
|
||||
export default {
|
||||
path: "/pure-admin-doc",
|
||||
redirect: "/pure-admin-doc/index",
|
||||
meta: {
|
||||
icon: hot,
|
||||
title: "pure-admin-doc",
|
||||
rank: doc
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: "/pure-admin-doc/index",
|
||||
name: "FrameDoc",
|
||||
component: IFrame,
|
||||
meta: {
|
||||
title: "pure-admin-doc",
|
||||
frameSrc: "https://yiming_chang.gitee.io/pure-admin-doc/"
|
||||
}
|
||||
}
|
||||
]
|
||||
} as RouteConfigsTable;
|
||||
24
src/router/modules/pureutils.ts
Normal file
24
src/router/modules/pureutils.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { utils } from "@/router/enums";
|
||||
import hot from "@/assets/svg/hot.svg?component";
|
||||
const IFrame = () => import("@/layout/frameView.vue");
|
||||
|
||||
export default {
|
||||
path: "/pure-admin-utils",
|
||||
redirect: "/pure-admin-utils/index",
|
||||
meta: {
|
||||
icon: hot,
|
||||
title: "pure-admin-utils",
|
||||
rank: utils
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: "/pure-admin-utils/index",
|
||||
name: "FrameUtils",
|
||||
component: IFrame,
|
||||
meta: {
|
||||
title: "pure-admin-utils",
|
||||
frameSrc: "https://pure-admin-utils.netlify.app/"
|
||||
}
|
||||
}
|
||||
]
|
||||
} as RouteConfigsTable;
|
||||
@@ -1,8 +1,7 @@
|
||||
import { $t } from "@/plugins/i18n";
|
||||
import type { RouteConfigsTable } from "/#/index";
|
||||
const Layout = () => import("@/layout/index.vue");
|
||||
|
||||
const remainingRouter: Array<RouteConfigsTable> = [
|
||||
export default [
|
||||
{
|
||||
path: "/login",
|
||||
name: "Login",
|
||||
@@ -20,7 +19,7 @@ const remainingRouter: Array<RouteConfigsTable> = [
|
||||
icon: "home-filled",
|
||||
title: $t("menus.hshome"),
|
||||
showLink: false,
|
||||
rank: 104
|
||||
rank: 102
|
||||
},
|
||||
children: [
|
||||
{
|
||||
@@ -38,9 +37,7 @@ const remainingRouter: Array<RouteConfigsTable> = [
|
||||
meta: {
|
||||
title: $t("menus.hsempty"),
|
||||
showLink: false,
|
||||
rank: 105
|
||||
rank: 103
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
export default remainingRouter;
|
||||
] as Array<RouteConfigsTable>;
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { $t } from "@/plugins/i18n";
|
||||
import type { RouteConfigsTable } from "/#/index";
|
||||
import { result } from "@/router/enums";
|
||||
|
||||
const resultRouter: RouteConfigsTable = {
|
||||
export default {
|
||||
path: "/result",
|
||||
redirect: "/result/success",
|
||||
meta: {
|
||||
icon: "checkbox-circle-line",
|
||||
title: $t("menus.hsResult"),
|
||||
rank: 8
|
||||
rank: result
|
||||
},
|
||||
children: [
|
||||
{
|
||||
@@ -27,6 +27,4 @@ const resultRouter: RouteConfigsTable = {
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
export default resultRouter;
|
||||
} as RouteConfigsTable;
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { $t } from "@/plugins/i18n";
|
||||
import { table } from "@/router/enums";
|
||||
import hot from "@/assets/svg/hot.svg?component";
|
||||
import type { RouteConfigsTable } from "/#/index";
|
||||
|
||||
const flowChartRouter: RouteConfigsTable = {
|
||||
export default {
|
||||
path: "/pure-table",
|
||||
redirect: "/pure-table/index",
|
||||
meta: {
|
||||
icon: hot,
|
||||
title: "pure-admin-table",
|
||||
rank: 4
|
||||
rank: table
|
||||
},
|
||||
children: [
|
||||
{
|
||||
@@ -28,6 +28,4 @@ const flowChartRouter: RouteConfigsTable = {
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
export default flowChartRouter;
|
||||
} as RouteConfigsTable;
|
||||
|
||||
23
src/router/modules/tree.ts
Normal file
23
src/router/modules/tree.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { $t } from "@/plugins/i18n";
|
||||
import { tree } from "@/router/enums";
|
||||
import hot from "@/assets/svg/hot.svg?component";
|
||||
|
||||
export default {
|
||||
path: "/tree",
|
||||
redirect: "/tree/index",
|
||||
meta: {
|
||||
icon: hot,
|
||||
title: $t("menus.hsTree"),
|
||||
rank: tree
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: "/tree/index",
|
||||
name: "Tree",
|
||||
component: () => import("@/views/tree/index.vue"),
|
||||
meta: {
|
||||
title: $t("menus.hsTree")
|
||||
}
|
||||
}
|
||||
]
|
||||
} as RouteConfigsTable;
|
||||
@@ -1,9 +0,0 @@
|
||||
import { RouteLocationNormalized } from "vue-router";
|
||||
|
||||
export interface toRouteType extends RouteLocationNormalized {
|
||||
meta: {
|
||||
roles: Array<string>;
|
||||
keepAlive?: boolean;
|
||||
dynamicLevel?: string;
|
||||
};
|
||||
}
|
||||
@@ -14,9 +14,9 @@ import { RouteConfigs } from "@/layout/types";
|
||||
import {
|
||||
isString,
|
||||
storageSession,
|
||||
buildHierarchyTree,
|
||||
isIncludeAllChildren
|
||||
} from "@pureadmin/utils";
|
||||
import { buildHierarchyTree } from "@/utils/tree";
|
||||
import { cloneDeep, intersection } from "lodash-unified";
|
||||
import { sessionKey, type DataInfo } from "@/utils/auth";
|
||||
import { usePermissionStoreHook } from "@/store/modules/permission";
|
||||
|
||||
@@ -2,7 +2,6 @@ import { store } from "@/store";
|
||||
import { appType } from "./types";
|
||||
import { defineStore } from "pinia";
|
||||
import { getConfig } from "@/config";
|
||||
import type { StorageConfigs } from "/#/index";
|
||||
import { deviceDetection, storageLocal } from "@pureadmin/utils";
|
||||
|
||||
export const useAppStore = defineStore({
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { store } from "@/store";
|
||||
import { defineStore } from "pinia";
|
||||
import { getConfig } from "@/config";
|
||||
import type { StorageConfigs } from "/#/index";
|
||||
import { storageLocal } from "@pureadmin/utils";
|
||||
|
||||
export const useEpThemeStore = defineStore({
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { defineStore } from "pinia";
|
||||
import { store } from "@/store";
|
||||
import { isEqual } from "@pureadmin/utils";
|
||||
import type { StorageConfigs } from "/#/index";
|
||||
import { routerArrays } from "@/layout/types";
|
||||
import { multiType, positionType } from "./types";
|
||||
import { isUrl, storageLocal } from "@pureadmin/utils";
|
||||
|
||||
188
src/utils/tree.ts
Normal file
188
src/utils/tree.ts
Normal file
@@ -0,0 +1,188 @@
|
||||
/**
|
||||
* @description 提取菜单树中的每一项uniqueId
|
||||
* @param tree 树
|
||||
* @returns 每一项uniqueId组成的数组
|
||||
*/
|
||||
export const extractPathList = (tree: any[]): any => {
|
||||
if (!Array.isArray(tree)) {
|
||||
console.warn("tree must be an array");
|
||||
return [];
|
||||
}
|
||||
if (!tree || tree.length === 0) return [];
|
||||
const expandedPaths: Array<number | string> = [];
|
||||
for (const node of tree) {
|
||||
const hasChildren = node.children && node.children.length > 0;
|
||||
if (hasChildren) {
|
||||
extractPathList(node.children);
|
||||
}
|
||||
expandedPaths.push(node.uniqueId);
|
||||
}
|
||||
return expandedPaths;
|
||||
};
|
||||
|
||||
/**
|
||||
* @description 如果父级下children的length为1,删除children并自动组建唯一uniqueId
|
||||
* @param tree 树
|
||||
* @param pathList 每一项的id组成的数组
|
||||
* @returns 组件唯一uniqueId后的树
|
||||
*/
|
||||
export const deleteChildren = (tree: any[], pathList = []): any => {
|
||||
if (!Array.isArray(tree)) {
|
||||
console.warn("menuTree must be an array");
|
||||
return [];
|
||||
}
|
||||
if (!tree || tree.length === 0) return [];
|
||||
for (const [key, node] of tree.entries()) {
|
||||
if (node.children && node.children.length === 1) delete node.children;
|
||||
node.id = key;
|
||||
node.parentId = pathList.length ? pathList[pathList.length - 1] : null;
|
||||
node.pathList = [...pathList, node.id];
|
||||
node.uniqueId =
|
||||
node.pathList.length > 1 ? node.pathList.join("-") : node.pathList[0];
|
||||
const hasChildren = node.children && node.children.length > 0;
|
||||
if (hasChildren) {
|
||||
deleteChildren(node.children, node.pathList);
|
||||
}
|
||||
}
|
||||
return tree;
|
||||
};
|
||||
|
||||
/**
|
||||
* @description 创建层级关系
|
||||
* @param tree 树
|
||||
* @param pathList 每一项的id组成的数组
|
||||
* @returns 创建层级关系后的树
|
||||
*/
|
||||
export const buildHierarchyTree = (tree: any[], pathList = []): any => {
|
||||
if (!Array.isArray(tree)) {
|
||||
console.warn("tree must be an array");
|
||||
return [];
|
||||
}
|
||||
if (!tree || tree.length === 0) return [];
|
||||
for (const [key, node] of tree.entries()) {
|
||||
node.id = key;
|
||||
node.parentId = pathList.length ? pathList[pathList.length - 1] : null;
|
||||
node.pathList = [...pathList, node.id];
|
||||
const hasChildren = node.children && node.children.length > 0;
|
||||
if (hasChildren) {
|
||||
buildHierarchyTree(node.children, node.pathList);
|
||||
}
|
||||
}
|
||||
return tree;
|
||||
};
|
||||
|
||||
/**
|
||||
* @description 广度优先遍历,根据唯一uniqueId找当前节点信息
|
||||
* @param tree 树
|
||||
* @param uniqueId 唯一uniqueId
|
||||
* @returns 当前节点信息
|
||||
*/
|
||||
export const getNodeByUniqueId = (
|
||||
tree: any[],
|
||||
uniqueId: number | string
|
||||
): any => {
|
||||
if (!Array.isArray(tree)) {
|
||||
console.warn("menuTree must be an array");
|
||||
return [];
|
||||
}
|
||||
if (!tree || tree.length === 0) return [];
|
||||
const item = tree.find(node => node.uniqueId === uniqueId);
|
||||
if (item) return item;
|
||||
const childrenList = tree
|
||||
.filter(node => node.children)
|
||||
.map(i => i.children)
|
||||
.flat(1) as unknown;
|
||||
return getNodeByUniqueId(childrenList as any[], uniqueId);
|
||||
};
|
||||
|
||||
/**
|
||||
* @description 向当前唯一uniqueId节点中追加字段
|
||||
* @param tree 树
|
||||
* @param uniqueId 唯一uniqueId
|
||||
* @param fields 需要追加的字段
|
||||
* @returns 追加字段后的树
|
||||
*/
|
||||
export const appendFieldByUniqueId = (
|
||||
tree: any[],
|
||||
uniqueId: number | string,
|
||||
fields: object
|
||||
): any => {
|
||||
if (!Array.isArray(tree)) {
|
||||
console.warn("menuTree must be an array");
|
||||
return [];
|
||||
}
|
||||
if (!tree || tree.length === 0) return [];
|
||||
for (const node of tree) {
|
||||
const hasChildren = node.children && node.children.length > 0;
|
||||
if (
|
||||
node.uniqueId === uniqueId &&
|
||||
Object.prototype.toString.call(fields) === "[object Object]"
|
||||
)
|
||||
Object.assign(node, fields);
|
||||
if (hasChildren) {
|
||||
appendFieldByUniqueId(node.children, uniqueId, fields);
|
||||
}
|
||||
}
|
||||
return tree;
|
||||
};
|
||||
|
||||
/**
|
||||
* @description 构造树型结构数据
|
||||
* @param data 数据源
|
||||
* @param id id字段 默认id
|
||||
* @param parentId 父节点字段,默认parentId
|
||||
* @param children 子节点字段,默认children
|
||||
* @returns 追加字段后的树
|
||||
*/
|
||||
export const handleTree = (
|
||||
data: any[],
|
||||
id?: string,
|
||||
parentId?: string,
|
||||
children?: string
|
||||
): any => {
|
||||
if (!Array.isArray(data)) {
|
||||
console.warn("data must be an array");
|
||||
return [];
|
||||
}
|
||||
const config = {
|
||||
id: id || "id",
|
||||
parentId: parentId || "parentId",
|
||||
childrenList: children || "children"
|
||||
};
|
||||
|
||||
const childrenListMap: any = {};
|
||||
const nodeIds: any = {};
|
||||
const tree = [];
|
||||
|
||||
for (const d of data) {
|
||||
const parentId = d[config.parentId];
|
||||
if (childrenListMap[parentId] == null) {
|
||||
childrenListMap[parentId] = [];
|
||||
}
|
||||
nodeIds[d[config.id]] = d;
|
||||
childrenListMap[parentId].push(d);
|
||||
}
|
||||
|
||||
for (const d of data) {
|
||||
const parentId = d[config.parentId];
|
||||
if (nodeIds[parentId] == null) {
|
||||
tree.push(d);
|
||||
}
|
||||
}
|
||||
|
||||
for (const t of tree) {
|
||||
adaptToChildrenList(t);
|
||||
}
|
||||
|
||||
function adaptToChildrenList(o: Record<string, any>) {
|
||||
if (childrenListMap[o[config.id]] !== null) {
|
||||
o[config.childrenList] = childrenListMap[o[config.id]];
|
||||
}
|
||||
if (o[config.childrenList]) {
|
||||
for (const c of o[config.childrenList]) {
|
||||
adaptToChildrenList(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
return tree;
|
||||
};
|
||||
@@ -3,7 +3,7 @@ import { computed } from "vue";
|
||||
import { clone } from "@pureadmin/utils";
|
||||
import { transformI18n } from "@/plugins/i18n";
|
||||
import ElTreeLine from "@/components/ReTreeLine";
|
||||
import { extractPathList, deleteChildren } from "@pureadmin/utils";
|
||||
import { extractPathList, deleteChildren } from "@/utils/tree";
|
||||
import { usePermissionStoreHook } from "@/store/modules/permission";
|
||||
|
||||
defineOptions({
|
||||
|
||||
@@ -4,7 +4,7 @@ import { clone } from "@pureadmin/utils";
|
||||
import type { ElTreeV2 } from "element-plus";
|
||||
import { transformI18n } from "@/plugins/i18n";
|
||||
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
|
||||
import { extractPathList, deleteChildren } from "@pureadmin/utils";
|
||||
import { extractPathList, deleteChildren } from "@/utils/tree";
|
||||
import { usePermissionStoreHook } from "@/store/modules/permission";
|
||||
import type { TreeNode } from "element-plus/es/components/tree-v2/src/types";
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import { useColumns } from "./columns";
|
||||
import { handleTree } from "@/utils/tree";
|
||||
import { getDeptList } from "@/api/system";
|
||||
import { FormInstance } from "element-plus";
|
||||
import { handleTree } from "@pureadmin/utils";
|
||||
import { reactive, ref, onMounted } from "vue";
|
||||
import { TableProBar } from "@/components/ReTable";
|
||||
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { handleTree } from "@/utils/tree";
|
||||
import type { ElTree } from "element-plus";
|
||||
import { getDeptList } from "@/api/system";
|
||||
import { handleTree } from "@pureadmin/utils";
|
||||
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
|
||||
import { ref, watch, onMounted, getCurrentInstance } from "vue";
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
deleteChildren,
|
||||
getNodeByUniqueId,
|
||||
appendFieldByUniqueId
|
||||
} from "@pureadmin/utils";
|
||||
} from "@/utils/tree";
|
||||
import { useDetail } from "./hooks";
|
||||
|
||||
defineOptions({
|
||||
|
||||
7
src/views/tree/index.vue
Normal file
7
src/views/tree/index.vue
Normal file
@@ -0,0 +1,7 @@
|
||||
<script setup lang="ts"></script>
|
||||
|
||||
<template>
|
||||
<div>即将发布</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
Reference in New Issue
Block a user