mirror of
https://github.com/pure-admin/vue-pure-admin.git
synced 2025-06-06 16:37:18 +08:00
refactor: 标签页重构,采用响应式storage
This commit is contained in:
parent
6a89af382f
commit
8177de106b
14
package-lock.json
generated
14
package-lock.json
generated
@ -27,7 +27,7 @@
|
|||||||
"path-to-regexp": "^6.2.0",
|
"path-to-regexp": "^6.2.0",
|
||||||
"pinia": "^2.0.0-beta.2",
|
"pinia": "^2.0.0-beta.2",
|
||||||
"resize-observer-polyfill": "^1.5.1",
|
"resize-observer-polyfill": "^1.5.1",
|
||||||
"responsive-storage": "^1.0.1",
|
"responsive-storage": "^1.0.4",
|
||||||
"v-contextmenu": "^3.0.0",
|
"v-contextmenu": "^3.0.0",
|
||||||
"vue": "^3.1.1",
|
"vue": "^3.1.1",
|
||||||
"vue-i18n": "^9.1.6",
|
"vue-i18n": "^9.1.6",
|
||||||
@ -2476,9 +2476,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/responsive-storage": {
|
"node_modules/responsive-storage": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/responsive-storage/-/responsive-storage-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/responsive-storage/-/responsive-storage-1.0.4.tgz",
|
||||||
"integrity": "sha512-p9HXODNHkdRUgaJ+mm6qKhsQCgWo1bGHAUlvbb4II5yJnb189Hrb8kKxHfG1KlbrnAQ2wR60a2BLq1AoDLp2nA==",
|
"integrity": "sha512-egiborkG1SMM5rQYMb0J0tdnDa/yH4h4ptA/fEcMAEoSaAe9j+Z4TMHFMb8x3BrM02StNuO8sNwbwVxLj+xzcA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"vue": "^3.1.1"
|
"vue": "^3.1.1"
|
||||||
}
|
}
|
||||||
@ -5067,9 +5067,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"responsive-storage": {
|
"responsive-storage": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/responsive-storage/-/responsive-storage-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/responsive-storage/-/responsive-storage-1.0.4.tgz",
|
||||||
"integrity": "sha512-p9HXODNHkdRUgaJ+mm6qKhsQCgWo1bGHAUlvbb4II5yJnb189Hrb8kKxHfG1KlbrnAQ2wR60a2BLq1AoDLp2nA==",
|
"integrity": "sha512-egiborkG1SMM5rQYMb0J0tdnDa/yH4h4ptA/fEcMAEoSaAe9j+Z4TMHFMb8x3BrM02StNuO8sNwbwVxLj+xzcA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"vue": "^3.1.1"
|
"vue": "^3.1.1"
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
},
|
},
|
||||||
"husky": {
|
"husky": {
|
||||||
"hooks": {
|
"hooks": {
|
||||||
"commit-msg": "node scripts/verify-commit.ts"
|
"commit-msg": "node scripts/verify-commit.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -35,7 +35,7 @@
|
|||||||
"path-to-regexp": "^6.2.0",
|
"path-to-regexp": "^6.2.0",
|
||||||
"pinia": "^2.0.0-beta.2",
|
"pinia": "^2.0.0-beta.2",
|
||||||
"resize-observer-polyfill": "^1.5.1",
|
"resize-observer-polyfill": "^1.5.1",
|
||||||
"responsive-storage": "^1.0.1",
|
"responsive-storage": "^1.0.4",
|
||||||
"v-contextmenu": "^3.0.0",
|
"v-contextmenu": "^3.0.0",
|
||||||
"vue": "^3.1.1",
|
"vue": "^3.1.1",
|
||||||
"vue-i18n": "^9.1.6",
|
"vue-i18n": "^9.1.6",
|
||||||
|
22
scripts/verify-commit.js
Normal file
22
scripts/verify-commit.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
const chalk = require("chalk")
|
||||||
|
|
||||||
|
const msgPath = process.env.HUSKY_GIT_PARAMS
|
||||||
|
const msg = require("fs").readFileSync(msgPath, "utf-8").trim()
|
||||||
|
|
||||||
|
const commitRE = /^(revert: )?(feat|fix|polish|docs|style|refactor|perf|test|workflow|ci|chore|types)(\(.+\))?: .{1,50}/
|
||||||
|
|
||||||
|
if (!commitRE.test(msg)) {
|
||||||
|
console.error(
|
||||||
|
` ${chalk.bgRed.white(" ERROR ")} ${chalk.red(
|
||||||
|
"不合法的 commit 消息格式"
|
||||||
|
)}\n\n` +
|
||||||
|
chalk.red(" 请使用正确的提交格式:\n\n") +
|
||||||
|
` ${chalk.green("feat: add 'comments' option")}\n` +
|
||||||
|
` ${chalk.green("fix: handle events on blur (close #28)")}\n\n` +
|
||||||
|
chalk.red(
|
||||||
|
" 请查看 git commit 提交规范:https://github.com/vuejs/vue/blob/dev/.github/COMMIT_CONVENTION.md \n"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
process.exit(1)
|
||||||
|
}
|
@ -1,23 +0,0 @@
|
|||||||
const chalk = require("chalk");
|
|
||||||
|
|
||||||
const msgPath = process.env.HUSKY_GIT_PARAMS;
|
|
||||||
const msg = require("fs").readFileSync(msgPath, "utf-8").trim();
|
|
||||||
|
|
||||||
const commitRE = /^(revert: )?(feat|fix|polish|docs|style|refactor|perf|test|workflow|ci|chore|types)(\(.+\))?: .{1,50}/;
|
|
||||||
|
|
||||||
if (!commitRE.test(msg)) {
|
|
||||||
console.log();
|
|
||||||
console.error(
|
|
||||||
` ${chalk.bgRed.white(" ERROR ")} ${chalk.red(
|
|
||||||
"不合法的 commit 消息格式"
|
|
||||||
)}\n\n` +
|
|
||||||
chalk.red(" 请使用正确的提交格式:\n\n") +
|
|
||||||
` ${chalk.green("feat: add 'comments' option")}\n` +
|
|
||||||
` ${chalk.green("fix: handle events on blur (close #28)")}\n\n` +
|
|
||||||
chalk.red(
|
|
||||||
" 请查看 git commit 提交规范:https://github.com/vuejs/vue/blob/dev/.github/COMMIT_CONVENTION.md \n"
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
@ -34,7 +34,6 @@ import { useRoute, useRouter } from "vue-router";
|
|||||||
import { useAppStoreHook } from "/@/store/modules/app";
|
import { useAppStoreHook } from "/@/store/modules/app";
|
||||||
import SidebarItem from "./SidebarItem.vue";
|
import SidebarItem from "./SidebarItem.vue";
|
||||||
import { algorithm } from "../../../utils/algorithm";
|
import { algorithm } from "../../../utils/algorithm";
|
||||||
import { useDynamicRoutesHook } from "../tag/tagsHook";
|
|
||||||
import { emitter } from "/@/utils/mitt";
|
import { emitter } from "/@/utils/mitt";
|
||||||
import Logo from "./Logo.vue";
|
import Logo from "./Logo.vue";
|
||||||
import { storageLocal } from "/@/utils/storage";
|
import { storageLocal } from "/@/utils/storage";
|
||||||
@ -62,8 +61,6 @@ export default defineComponent({
|
|||||||
return path;
|
return path;
|
||||||
});
|
});
|
||||||
|
|
||||||
const { dynamicRouteTags } = useDynamicRoutesHook();
|
|
||||||
|
|
||||||
const menuSelect = (indexPath: string): void => {
|
const menuSelect = (indexPath: string): void => {
|
||||||
let parentPath = "";
|
let parentPath = "";
|
||||||
let parentPathIndex = indexPath.lastIndexOf("/");
|
let parentPathIndex = indexPath.lastIndexOf("/");
|
||||||
@ -74,7 +71,11 @@ export default defineComponent({
|
|||||||
function findCurrentRoute(routes) {
|
function findCurrentRoute(routes) {
|
||||||
return routes.map((item, key) => {
|
return routes.map((item, key) => {
|
||||||
if (item.path === indexPath) {
|
if (item.path === indexPath) {
|
||||||
dynamicRouteTags(indexPath, parentPath, item);
|
// 切换左侧菜单 通知标签页
|
||||||
|
emitter.emit("changLayoutRoute", {
|
||||||
|
indexPath,
|
||||||
|
parentPath
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
if (item.children) findCurrentRoute(item.children);
|
if (item.children) findCurrentRoute(item.children);
|
||||||
}
|
}
|
||||||
@ -82,7 +83,6 @@ export default defineComponent({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
findCurrentRoute(algorithm.increaseIndexes(router));
|
findCurrentRoute(algorithm.increaseIndexes(router));
|
||||||
emitter.emit("changLayoutRoute", indexPath);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
onBeforeMount(() => {
|
onBeforeMount(() => {
|
||||||
|
@ -72,8 +72,6 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang='ts'>
|
<script lang='ts'>
|
||||||
import { useDynamicRoutesHook } from "./tagsHook";
|
|
||||||
import { useRoute, useRouter } from "vue-router";
|
|
||||||
import {
|
import {
|
||||||
ref,
|
ref,
|
||||||
watchEffect,
|
watchEffect,
|
||||||
@ -83,22 +81,39 @@ import {
|
|||||||
nextTick,
|
nextTick,
|
||||||
getCurrentInstance
|
getCurrentInstance
|
||||||
} from "vue";
|
} from "vue";
|
||||||
|
import { useRoute, useRouter } from "vue-router";
|
||||||
import { storageLocal } from "/@/utils/storage";
|
import { storageLocal } from "/@/utils/storage";
|
||||||
import { emitter } from "/@/utils/mitt";
|
import { emitter } from "/@/utils/mitt";
|
||||||
import { toggleClass, removeClass, hasClass } from "/@/utils/operate";
|
import { toggleClass, removeClass, hasClass } from "/@/utils/operate";
|
||||||
import { templateRef } from "@vueuse/core";
|
import { templateRef } from "@vueuse/core";
|
||||||
import { homeRoute } from "./type";
|
|
||||||
let refreshButton = "refresh-button";
|
let refreshButton = "refresh-button";
|
||||||
|
|
||||||
|
let routerArrays = [
|
||||||
|
{
|
||||||
|
path: "/welcome",
|
||||||
|
meta: {
|
||||||
|
title: "message.hshome",
|
||||||
|
icon: "el-icon-s-home",
|
||||||
|
showLink: true,
|
||||||
|
savedPosition: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
export default {
|
export default {
|
||||||
|
computed: {
|
||||||
|
dynamicTagList() {
|
||||||
|
if (
|
||||||
|
!this.$storage.routesInStorage ||
|
||||||
|
this.$storage.routesInStorage.length === 0
|
||||||
|
) {
|
||||||
|
this.$storage.routesInStorage = routerArrays;
|
||||||
|
}
|
||||||
|
return this.$storage.routesInStorage;
|
||||||
|
}
|
||||||
|
},
|
||||||
setup() {
|
setup() {
|
||||||
let vm: any;
|
let vm: any;
|
||||||
const {
|
let st: any;
|
||||||
deleteDynamicTag,
|
|
||||||
dynamicRouteTags,
|
|
||||||
dRoutes,
|
|
||||||
routesLength
|
|
||||||
} = useDynamicRoutesHook();
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const showTags = ref(storageLocal.getItem("tagsVal") || false);
|
const showTags = ref(storageLocal.getItem("tagsVal") || false);
|
||||||
@ -116,21 +131,21 @@ export default {
|
|||||||
icon: "el-icon-close",
|
icon: "el-icon-close",
|
||||||
text: "关闭当前标签页",
|
text: "关闭当前标签页",
|
||||||
divided: false,
|
divided: false,
|
||||||
disabled: unref(routesLength) > 1 ? false : true,
|
disabled: routerArrays.length > 1 ? false : true,
|
||||||
show: true
|
show: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: "el-icon-more",
|
icon: "el-icon-more",
|
||||||
text: "关闭其他标签页",
|
text: "关闭其他标签页",
|
||||||
divided: true,
|
divided: true,
|
||||||
disabled: unref(routesLength) > 2 ? false : true,
|
disabled: routerArrays.length > 2 ? false : true,
|
||||||
show: true
|
show: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: "el-icon-minus",
|
icon: "el-icon-minus",
|
||||||
text: "关闭全部标签页",
|
text: "关闭全部标签页",
|
||||||
divided: false,
|
divided: false,
|
||||||
disabled: unref(routesLength) > 1 ? false : true,
|
disabled: routerArrays.length > 1 ? false : true,
|
||||||
show: true
|
show: true
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
@ -148,30 +163,33 @@ export default {
|
|||||||
// 当前右键选中的路由信息
|
// 当前右键选中的路由信息
|
||||||
let currentSelect = ref({});
|
let currentSelect = ref({});
|
||||||
|
|
||||||
function deleteMenu(item) {
|
function dynamicRouteTag(value: string, parentPath: string): void {
|
||||||
let tagslen = storageLocal.getItem("routesInStorage").length;
|
const hasValue = st.routesInStorage.some((item: any) => {
|
||||||
if (tagslen === 2) {
|
return item.path === value;
|
||||||
Array.from([1, 2, 3]).forEach(v => {
|
});
|
||||||
tagsViews.value[v].disabled = true;
|
|
||||||
});
|
function concatPath(arr: object[], value: string, parentPath: string) {
|
||||||
|
if (!hasValue) {
|
||||||
|
arr.forEach((arrItem: any) => {
|
||||||
|
let pathConcat = parentPath + arrItem.path;
|
||||||
|
if (arrItem.path === value || pathConcat === value) {
|
||||||
|
routerArrays.push({
|
||||||
|
path: value,
|
||||||
|
meta: arrItem.meta
|
||||||
|
});
|
||||||
|
st.routesInStorage = routerArrays;
|
||||||
|
} else {
|
||||||
|
if (arrItem.children && arrItem.children.length > 0) {
|
||||||
|
concatPath(arrItem.children, value, parentPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (tagslen === 3) {
|
concatPath(router.options.routes, value, parentPath);
|
||||||
tagsViews.value[2].disabled = true;
|
|
||||||
}
|
|
||||||
deleteDynamicTag(item, route.path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化页面刷新保证当前路由tabview存在
|
// 重新加载
|
||||||
let stop = watchEffect(() => {
|
|
||||||
let parentPath = route.path.slice(0, route.path.lastIndexOf("/"));
|
|
||||||
dynamicRouteTags(route.path, parentPath, route);
|
|
||||||
});
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
// 监听只执行一次,但获取不到当前路由,需要下一个事件轮询中取消监听
|
|
||||||
stop();
|
|
||||||
});
|
|
||||||
|
|
||||||
function onFresh() {
|
function onFresh() {
|
||||||
toggleClass(true, refreshButton, document.querySelector(".rotate"));
|
toggleClass(true, refreshButton, document.querySelector(".rotate"));
|
||||||
const { path, fullPath } = unref(route);
|
const { path, fullPath } = unref(route);
|
||||||
@ -183,6 +201,57 @@ export default {
|
|||||||
}, 600);
|
}, 600);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function deleteDynamicTag(obj: any, current: any, other: any) {
|
||||||
|
let valueIndex: number = routerArrays.findIndex((item: any) => {
|
||||||
|
return item.path === obj.path;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (other) {
|
||||||
|
st.routesInStorage = routerArrays = [
|
||||||
|
{
|
||||||
|
path: "/welcome",
|
||||||
|
meta: {
|
||||||
|
title: "message.hshome",
|
||||||
|
icon: "el-icon-s-home",
|
||||||
|
showLink: true,
|
||||||
|
savedPosition: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
obj
|
||||||
|
];
|
||||||
|
router.push(obj.path);
|
||||||
|
Array.from([2]).forEach(v => {
|
||||||
|
tagsViews.value[v].disabled = true;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 从当前匹配到的路径中删除
|
||||||
|
routerArrays.splice(valueIndex, 1);
|
||||||
|
st.routesInStorage = routerArrays;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current === obj.path) {
|
||||||
|
// 如果删除当前激活tag就自动切换到最后一个tag
|
||||||
|
let newRoute: any = routerArrays.slice(-1);
|
||||||
|
nextTick(() => {
|
||||||
|
router.push({
|
||||||
|
path: newRoute[0].path
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteMenu(item, other = false) {
|
||||||
|
if (routerArrays.length === 2) {
|
||||||
|
Array.from([1, 2, 3]).forEach(v => {
|
||||||
|
tagsViews.value[v].disabled = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (routerArrays.length === 3) {
|
||||||
|
tagsViews.value[2].disabled = true;
|
||||||
|
}
|
||||||
|
deleteDynamicTag(item, route.path, other);
|
||||||
|
}
|
||||||
|
|
||||||
function onClickDrop(key, item, selectRoute) {
|
function onClickDrop(key, item, selectRoute) {
|
||||||
if (item && item.disabled) return;
|
if (item && item.disabled) return;
|
||||||
// 当前路由信息
|
// 当前路由信息
|
||||||
@ -199,17 +268,20 @@ export default {
|
|||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
// 关闭其他标签页
|
// 关闭其他标签页
|
||||||
dRoutes.value = selectRoute
|
selectRoute
|
||||||
? [homeRoute, { path: selectRoute.path, meta: selectRoute.meta }]
|
? deleteMenu(
|
||||||
: [homeRoute, { path: route.path, meta: route.meta }];
|
{
|
||||||
storageLocal.setItem("routesInStorage", dRoutes.value);
|
path: selectRoute.path,
|
||||||
tagsViews.value[2].disabled = true;
|
meta: selectRoute.meta
|
||||||
if (selectRoute) router.push(selectRoute.path);
|
},
|
||||||
|
true
|
||||||
|
)
|
||||||
|
: deleteMenu({ path: route.path, meta: route.meta }, true);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
// 关闭全部标签页
|
// 关闭全部标签页
|
||||||
dRoutes.value = [homeRoute];
|
routerArrays.splice(1, routerArrays.length);
|
||||||
storageLocal.setItem("routesInStorage", dRoutes.value);
|
st.routesInStorage = routerArrays;
|
||||||
router.push("/welcome");
|
router.push("/welcome");
|
||||||
Array.from([1, 2, 3]).forEach(v => {
|
Array.from([1, 2, 3]).forEach(v => {
|
||||||
tagsViews.value[v].disabled = true;
|
tagsViews.value[v].disabled = true;
|
||||||
@ -235,6 +307,12 @@ export default {
|
|||||||
Array.from([1, 2, 3]).forEach(v => {
|
Array.from([1, 2, 3]).forEach(v => {
|
||||||
tagsViews.value[v].show = true;
|
tagsViews.value[v].show = true;
|
||||||
});
|
});
|
||||||
|
} else if (st.routesInStorage.length === 2) {
|
||||||
|
// 只有两个标签时不显示关闭其他标签页
|
||||||
|
tagsViews.value[2].show = false;
|
||||||
|
Array.from([0, 1, 3]).forEach(v => {
|
||||||
|
tagsViews.value[v].show = true;
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
Array.from([0, 1, 2, 3]).forEach(v => {
|
Array.from([0, 1, 2, 3]).forEach(v => {
|
||||||
tagsViews.value[v].show = true;
|
tagsViews.value[v].show = true;
|
||||||
@ -260,17 +338,6 @@ export default {
|
|||||||
visible.value = false;
|
visible.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(
|
|
||||||
() => visible.value,
|
|
||||||
val => {
|
|
||||||
if (val) {
|
|
||||||
document.body.addEventListener("click", closeMenu);
|
|
||||||
} else {
|
|
||||||
document.body.removeEventListener("click", closeMenu);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// 鼠标移入
|
// 鼠标移入
|
||||||
function onMouseenter(item, index) {
|
function onMouseenter(item, index) {
|
||||||
if (index) activeIndex.value = index;
|
if (index) activeIndex.value = index;
|
||||||
@ -299,8 +366,20 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => visible.value,
|
||||||
|
val => {
|
||||||
|
if (val) {
|
||||||
|
document.body.addEventListener("click", closeMenu);
|
||||||
|
} else {
|
||||||
|
document.body.removeEventListener("click", closeMenu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
onBeforeMount(() => {
|
onBeforeMount(() => {
|
||||||
vm = getCurrentInstance();
|
vm = getCurrentInstance();
|
||||||
|
st = vm.appContext.app.config.globalProperties.$storage;
|
||||||
|
|
||||||
emitter.on("tagViewsChange", key => {
|
emitter.on("tagViewsChange", key => {
|
||||||
if (unref(showTags) === key) return;
|
if (unref(showTags) === key) return;
|
||||||
@ -311,14 +390,16 @@ export default {
|
|||||||
showModel.value = key;
|
showModel.value = key;
|
||||||
});
|
});
|
||||||
|
|
||||||
emitter.on("changLayoutRoute", indexPath => {
|
// 接收侧边栏切换传递过来的参数
|
||||||
let currentLen = storageLocal.getItem("routesInStorage").length;
|
emitter.on("changLayoutRoute", ({ indexPath, parentPath }) => {
|
||||||
if (currentLen === 1) {
|
dynamicRouteTag(indexPath, parentPath);
|
||||||
|
|
||||||
|
if (routerArrays.length === 2) {
|
||||||
Array.from([1, 3]).forEach(v => {
|
Array.from([1, 3]).forEach(v => {
|
||||||
tagsViews.value[v].disabled = false;
|
tagsViews.value[v].disabled = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (currentLen >= 2) {
|
if (routerArrays.length > 2) {
|
||||||
Array.from([1, 2, 3]).forEach(v => {
|
Array.from([1, 2, 3]).forEach(v => {
|
||||||
tagsViews.value[v].disabled = false;
|
tagsViews.value[v].disabled = false;
|
||||||
});
|
});
|
||||||
@ -327,7 +408,6 @@ export default {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
dynamicTagList: useDynamicRoutesHook().dRoutes,
|
|
||||||
deleteMenu,
|
deleteMenu,
|
||||||
showTags,
|
showTags,
|
||||||
onFresh,
|
onFresh,
|
||||||
|
@ -1,120 +0,0 @@
|
|||||||
import { reactive, toRefs, unref, nextTick, computed } from "vue";
|
|
||||||
import { storageLocal } from "/@/utils/storage";
|
|
||||||
import { useRouter } from "vue-router";
|
|
||||||
import { homeRoute } from "./type";
|
|
||||||
|
|
||||||
interface InterDynamic {
|
|
||||||
dRoutes: object[];
|
|
||||||
[propName: string]: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 默认显示首页tag
|
|
||||||
let dynamic: InterDynamic = reactive({
|
|
||||||
dRoutes: [
|
|
||||||
{
|
|
||||||
path: "/welcome",
|
|
||||||
meta: {
|
|
||||||
title: "message.hshome",
|
|
||||||
icon: "el-icon-s-home",
|
|
||||||
showLink: true,
|
|
||||||
savedPosition: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
export function useDynamicRoutesHook() {
|
|
||||||
const router = useRouter();
|
|
||||||
const routesLength = computed(() => {
|
|
||||||
return storageLocal.getItem("routesInStorage")
|
|
||||||
? storageLocal.getItem("routesInStorage").length
|
|
||||||
: 0;
|
|
||||||
});
|
|
||||||
// 返回当前路由组成的数组
|
|
||||||
const routesStorageLists = computed(() => {
|
|
||||||
return storageLocal.getItem("routesInStorage")
|
|
||||||
? storageLocal.getItem("routesInStorage")
|
|
||||||
: [];
|
|
||||||
});
|
|
||||||
/**
|
|
||||||
* @param value string 当前menu对应的路由path
|
|
||||||
* @param parentPath string 当前路由中父级路由
|
|
||||||
*/
|
|
||||||
const dynamicRouteTags = (
|
|
||||||
value: string,
|
|
||||||
parentPath: string,
|
|
||||||
route: any
|
|
||||||
): void => {
|
|
||||||
nextTick(() => {
|
|
||||||
if (unref(routesStorageLists).length > 2) {
|
|
||||||
dynamic.dRoutes = unref(routesStorageLists);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const hasValue = dynamic.dRoutes.some((item: any) => {
|
|
||||||
return item.path === value;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (route) {
|
|
||||||
let ramStorage = storageLocal.getItem("routesInStorage");
|
|
||||||
nextTick(() => {
|
|
||||||
if (ramStorage) {
|
|
||||||
let currentIndex = ramStorage.findIndex((v) => v.path === route.path);
|
|
||||||
if (currentIndex !== -1) return;
|
|
||||||
ramStorage.push({ path: route.path, meta: route.meta });
|
|
||||||
storageLocal.setItem("routesInStorage", ramStorage);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function concatPath(arr: object[], value: string, parentPath: string) {
|
|
||||||
if (!hasValue) {
|
|
||||||
arr.forEach((arrItem: any) => {
|
|
||||||
let pathConcat = parentPath + "/" + arrItem.path;
|
|
||||||
if (arrItem.path === value || pathConcat === value) {
|
|
||||||
dynamic.dRoutes.push({ path: value, meta: arrItem.meta });
|
|
||||||
|
|
||||||
unref(routesLength) === 0
|
|
||||||
? storageLocal.setItem("routesInStorage", dynamic.dRoutes)
|
|
||||||
: [];
|
|
||||||
} else {
|
|
||||||
if (arrItem.children && arrItem.children.length > 0) {
|
|
||||||
concatPath(arrItem.children, value, parentPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
concatPath(router.options.routes, value, parentPath);
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* @param value any 当前删除tag路由
|
|
||||||
* @param current objct 当前激活路由对象
|
|
||||||
*/
|
|
||||||
const deleteDynamicTag = async (obj: any, current: any): Promise<any> => {
|
|
||||||
let valueIndex: number = dynamic.dRoutes.findIndex((item: any) => {
|
|
||||||
return item.path === obj.path;
|
|
||||||
});
|
|
||||||
// 从当前匹配到的路径中删除
|
|
||||||
await dynamic.dRoutes.splice(valueIndex, 1);
|
|
||||||
storageLocal.setItem("routesInStorage", dynamic.dRoutes);
|
|
||||||
if (current === obj.path) {
|
|
||||||
// 如果删除当前激活tag就自动切换到最后一个tag
|
|
||||||
let newRoute: any = dynamic.dRoutes.slice(-1);
|
|
||||||
nextTick(() => {
|
|
||||||
router.push({
|
|
||||||
path: newRoute[0].path,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
...toRefs(dynamic),
|
|
||||||
dynamicRouteTags,
|
|
||||||
deleteDynamicTag,
|
|
||||||
routesLength,
|
|
||||||
routesStorageLists,
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
interface RouteModel {
|
|
||||||
readonly path: string;
|
|
||||||
readonly meta: object;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 固定首页路由
|
|
||||||
export const homeRoute: RouteModel = {
|
|
||||||
path: "/welcome",
|
|
||||||
meta: {
|
|
||||||
title: "message.hshome",
|
|
||||||
icon: "el-icon-s-home",
|
|
||||||
showLink: true,
|
|
||||||
savedPosition: false,
|
|
||||||
},
|
|
||||||
};
|
|
@ -26,6 +26,7 @@ app.config.globalProperties.$config = getConfig();
|
|||||||
import Storage from "responsive-storage";
|
import Storage from "responsive-storage";
|
||||||
|
|
||||||
app.use(Storage, {
|
app.use(Storage, {
|
||||||
|
// 默认显示首页tag
|
||||||
routesInStorage: {
|
routesInStorage: {
|
||||||
type: String,
|
type: String,
|
||||||
default: Storage.getData(undefined, "routesInStorage") ?? [
|
default: Storage.getData(undefined, "routesInStorage") ?? [
|
||||||
|
@ -14,7 +14,7 @@ const nestedRouter = {
|
|||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: "menu1",
|
path: "/nested/menu1",
|
||||||
component: () => import("/@/views/nested/menu1/index.vue"),
|
component: () => import("/@/views/nested/menu1/index.vue"),
|
||||||
name: "Menu1",
|
name: "Menu1",
|
||||||
meta: {
|
meta: {
|
||||||
@ -25,7 +25,7 @@ const nestedRouter = {
|
|||||||
redirect: "/nested/menu1/menu1-1",
|
redirect: "/nested/menu1/menu1-1",
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: "menu1-1",
|
path: "/nested/menu1/menu1-1",
|
||||||
component: () => import("/@/views/nested/menu1/menu1-1/index.vue"),
|
component: () => import("/@/views/nested/menu1/menu1-1/index.vue"),
|
||||||
name: "Menu1-1",
|
name: "Menu1-1",
|
||||||
meta: {
|
meta: {
|
||||||
@ -35,7 +35,7 @@ const nestedRouter = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "menu1-2",
|
path: "/nested/menu1/menu1-2",
|
||||||
component: () => import("/@/views/nested/menu1/menu1-2/index.vue"),
|
component: () => import("/@/views/nested/menu1/menu1-2/index.vue"),
|
||||||
name: "Menu1-2",
|
name: "Menu1-2",
|
||||||
redirect: "/nested/menu1/menu1-2/menu1-2-1",
|
redirect: "/nested/menu1/menu1-2/menu1-2-1",
|
||||||
@ -46,7 +46,7 @@ const nestedRouter = {
|
|||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: "menu1-2-1",
|
path: "/nested/menu1/menu1-2/menu1-2-1",
|
||||||
component: () =>
|
component: () =>
|
||||||
import("/@/views/nested/menu1/menu1-2/menu1-2-1/index.vue"),
|
import("/@/views/nested/menu1/menu1-2/menu1-2-1/index.vue"),
|
||||||
name: "Menu1-2-1",
|
name: "Menu1-2-1",
|
||||||
@ -57,7 +57,7 @@ const nestedRouter = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "menu1-2-2",
|
path: "/nested/menu1/menu1-2/menu1-2-2",
|
||||||
component: () =>
|
component: () =>
|
||||||
import("/@/views/nested/menu1/menu1-2/menu1-2-2/index.vue"),
|
import("/@/views/nested/menu1/menu1-2/menu1-2-2/index.vue"),
|
||||||
name: "Menu1-2-2",
|
name: "Menu1-2-2",
|
||||||
@ -70,7 +70,7 @@ const nestedRouter = {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "menu1-3",
|
path: "/nested/menu1/menu1-3",
|
||||||
component: () => import("/@/views/nested/menu1/menu1-3/index.vue"),
|
component: () => import("/@/views/nested/menu1/menu1-3/index.vue"),
|
||||||
name: "Menu1-3",
|
name: "Menu1-3",
|
||||||
meta: {
|
meta: {
|
||||||
@ -82,7 +82,7 @@ const nestedRouter = {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "menu2",
|
path: "/nested/menu2",
|
||||||
name: "Menu2",
|
name: "Menu2",
|
||||||
component: () => import("/@/views/nested/menu2/index.vue"),
|
component: () => import("/@/views/nested/menu2/index.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user