mirror of
https://github.com/pure-admin/vue-pure-admin.git
synced 2025-06-07 08:57:19 +08:00
perf: layout (#50)
This commit is contained in:
parent
77b7abcbc3
commit
6b16a04229
1
src/assets/svg/globalization.svg
Normal file
1
src/assets/svg/globalization.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="globalization" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 512 512"><path d="M478.33 433.6l-90-218a22 22 0 0 0-40.67 0l-90 218a22 22 0 1 0 40.67 16.79L316.66 406h102.67l18.33 44.39A22 22 0 0 0 458 464a22 22 0 0 0 20.32-30.4zM334.83 362L368 281.65L401.17 362z" fill="currentColor"></path><path d="M267.84 342.92a22 22 0 0 0-4.89-30.7c-.2-.15-15-11.13-36.49-34.73c39.65-53.68 62.11-114.75 71.27-143.49H330a22 22 0 0 0 0-44H214V70a22 22 0 0 0-44 0v20H54a22 22 0 0 0 0 44h197.25c-9.52 26.95-27.05 69.5-53.79 108.36c-31.41-41.68-43.08-68.65-43.17-68.87a22 22 0 0 0-40.58 17c.58 1.38 14.55 34.23 52.86 83.93c.92 1.19 1.83 2.35 2.74 3.51c-39.24 44.35-77.74 71.86-93.85 80.74a22 22 0 1 0 21.07 38.63c2.16-1.18 48.6-26.89 101.63-85.59c22.52 24.08 38 35.44 38.93 36.1a22 22 0 0 0 30.75-4.9z" fill="currentColor"></path></svg>
|
After Width: | Height: | Size: 965 B |
@ -1 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconinternationality" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 512 512"><path d="M478.33 433.6l-90-218a22 22 0 0 0-40.67 0l-90 218a22 22 0 1 0 40.67 16.79L316.66 406h102.67l18.33 44.39A22 22 0 0 0 458 464a22 22 0 0 0 20.32-30.4zM334.83 362L368 281.65L401.17 362z" fill="currentColor"></path><path d="M267.84 342.92a22 22 0 0 0-4.89-30.7c-.2-.15-15-11.13-36.49-34.73c39.65-53.68 62.11-114.75 71.27-143.49H330a22 22 0 0 0 0-44H214V70a22 22 0 0 0-44 0v20H54a22 22 0 0 0 0 44h197.25c-9.52 26.95-27.05 69.5-53.79 108.36c-31.41-41.68-43.08-68.65-43.17-68.87a22 22 0 0 0-40.58 17c.58 1.38 14.55 34.23 52.86 83.93c.92 1.19 1.83 2.35 2.74 3.51c-39.24 44.35-77.74 71.86-93.85 80.74a22 22 0 1 0 21.07 38.63c2.16-1.18 48.6-26.89 101.63-85.59c22.52 24.08 38 35.44 38.93 36.1a22 22 0 0 0 30.75-4.9z" fill="currentColor"></path></svg>
|
|
Before Width: | Height: | Size: 972 B |
@ -1,10 +0,0 @@
|
|||||||
import { App } from "vue";
|
|
||||||
import reBreadCrumb from "./src/index.vue";
|
|
||||||
|
|
||||||
export const ReBreadCrumb = Object.assign(reBreadCrumb, {
|
|
||||||
install(app: App) {
|
|
||||||
app.component(reBreadCrumb.name, reBreadCrumb);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
export default ReBreadCrumb;
|
|
@ -1,3 +1,14 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from "vue";
|
||||||
|
const lists = ref<ForDataType<undefined>>([
|
||||||
|
{ type: "", label: "善良" },
|
||||||
|
{ type: "success", label: "好学" },
|
||||||
|
{ type: "info", label: "幽默" },
|
||||||
|
{ type: "danger", label: "旅游" },
|
||||||
|
{ type: "warning", label: "追剧" }
|
||||||
|
]);
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<el-descriptions
|
<el-descriptions
|
||||||
class="margin-top"
|
class="margin-top"
|
||||||
@ -75,17 +86,6 @@
|
|||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { ref } from "vue";
|
|
||||||
const lists = ref<ForDataType<undefined>>([
|
|
||||||
{ type: "", label: "善良" },
|
|
||||||
{ type: "success", label: "好学" },
|
|
||||||
{ type: "info", label: "幽默" },
|
|
||||||
{ type: "danger", label: "旅游" },
|
|
||||||
{ type: "warning", label: "追剧" }
|
|
||||||
]);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.el-tag--mini {
|
.el-tag--mini {
|
||||||
margin-right: 10px !important;
|
margin-right: 10px !important;
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
import { App } from "vue";
|
|
||||||
import reHamBurger from "./src/index.vue";
|
|
||||||
|
|
||||||
export const ReHamBurger = Object.assign(reHamBurger, {
|
|
||||||
install(app: App) {
|
|
||||||
app.component(reHamBurger.name, reHamBurger);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
export default ReHamBurger;
|
|
@ -1,3 +1,59 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { useI18n } from "vue-i18n";
|
||||||
|
import { emitter } from "/@/utils/mitt";
|
||||||
|
import Hamburger from "./sidebar/hamBurger.vue";
|
||||||
|
import { useRouter, useRoute } from "vue-router";
|
||||||
|
import { storageSession } from "/@/utils/storage";
|
||||||
|
import Breadcrumb from "./sidebar/breadCrumb.vue";
|
||||||
|
import { useAppStoreHook } from "/@/store/modules/app";
|
||||||
|
import { unref, watch, getCurrentInstance } from "vue";
|
||||||
|
import { deviceDetection } from "/@/utils/deviceDetection";
|
||||||
|
import screenfull from "../components/screenfull/index.vue";
|
||||||
|
import globalization from "/@/assets/svg/globalization.svg";
|
||||||
|
|
||||||
|
const instance =
|
||||||
|
getCurrentInstance().appContext.config.globalProperties.$storage;
|
||||||
|
const pureApp = useAppStoreHook();
|
||||||
|
const router = useRouter();
|
||||||
|
const route = useRoute();
|
||||||
|
let usename = storageSession.getItem("info")?.username;
|
||||||
|
const { locale, t } = useI18n();
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => locale.value,
|
||||||
|
() => {
|
||||||
|
//@ts-ignore
|
||||||
|
document.title = t(unref(route.meta.title)); // 动态title
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 退出登录
|
||||||
|
const logout = (): void => {
|
||||||
|
storageSession.removeItem("info");
|
||||||
|
router.push("/login");
|
||||||
|
};
|
||||||
|
|
||||||
|
function onPanel() {
|
||||||
|
emitter.emit("openPanel");
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleSideBar() {
|
||||||
|
pureApp.toggleSideBar();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 简体中文
|
||||||
|
function translationCh() {
|
||||||
|
instance.locale = { locale: "zh" };
|
||||||
|
locale.value = "zh";
|
||||||
|
}
|
||||||
|
|
||||||
|
// English
|
||||||
|
function translationEn() {
|
||||||
|
instance.locale = { locale: "en" };
|
||||||
|
locale.value = "en";
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="navbar">
|
<div class="navbar">
|
||||||
<Hamburger
|
<Hamburger
|
||||||
@ -13,7 +69,7 @@
|
|||||||
<screenfull v-show="!deviceDetection()" />
|
<screenfull v-show="!deviceDetection()" />
|
||||||
<!-- 国际化 -->
|
<!-- 国际化 -->
|
||||||
<el-dropdown trigger="click">
|
<el-dropdown trigger="click">
|
||||||
<iconinternationality />
|
<globalization />
|
||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
<el-dropdown-menu class="translation">
|
<el-dropdown-menu class="translation">
|
||||||
<el-dropdown-item
|
<el-dropdown-item
|
||||||
@ -60,99 +116,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import { defineComponent, unref, watch, getCurrentInstance } from "vue";
|
|
||||||
import Breadcrumb from "/@/components/ReBreadCrumb";
|
|
||||||
import Hamburger from "/@/components/ReHamBurger";
|
|
||||||
import screenfull from "../components/screenfull/index.vue";
|
|
||||||
import { useRouter, useRoute } from "vue-router";
|
|
||||||
import { useAppStoreHook } from "/@/store/modules/app";
|
|
||||||
import { storageSession } from "/@/utils/storage";
|
|
||||||
import favicon from "/favicon.ico";
|
|
||||||
import { emitter } from "/@/utils/mitt";
|
|
||||||
import { deviceDetection } from "/@/utils/deviceDetection";
|
|
||||||
import { useI18n } from "vue-i18n";
|
|
||||||
import iconinternationality from "/@/assets/svg/iconinternationality.svg";
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: "Navbar",
|
|
||||||
components: {
|
|
||||||
Breadcrumb,
|
|
||||||
Hamburger,
|
|
||||||
screenfull,
|
|
||||||
iconinternationality
|
|
||||||
},
|
|
||||||
// @ts-ignore
|
|
||||||
computed: {
|
|
||||||
// eslint-disable-next-line vue/return-in-computed-property
|
|
||||||
currentLocale() {
|
|
||||||
switch (this.$storage.locale?.locale) {
|
|
||||||
case "zh":
|
|
||||||
return true;
|
|
||||||
case "en":
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
setup() {
|
|
||||||
const instance =
|
|
||||||
getCurrentInstance().appContext.config.globalProperties.$storage;
|
|
||||||
const pureApp = useAppStoreHook();
|
|
||||||
const router = useRouter();
|
|
||||||
const route = useRoute();
|
|
||||||
let usename = storageSession.getItem("info")?.username;
|
|
||||||
const { locale, t } = useI18n();
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => locale.value,
|
|
||||||
() => {
|
|
||||||
//@ts-ignore
|
|
||||||
document.title = t(unref(route.meta.title)); // 动态title
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// 退出登录
|
|
||||||
const logout = (): void => {
|
|
||||||
storageSession.removeItem("info");
|
|
||||||
router.push("/login");
|
|
||||||
};
|
|
||||||
|
|
||||||
function onPanel() {
|
|
||||||
emitter.emit("openPanel");
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleSideBar() {
|
|
||||||
pureApp.toggleSideBar();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 简体中文
|
|
||||||
function translationCh() {
|
|
||||||
instance.locale = { locale: "zh" };
|
|
||||||
locale.value = "zh";
|
|
||||||
}
|
|
||||||
|
|
||||||
// English
|
|
||||||
function translationEn() {
|
|
||||||
instance.locale = { locale: "en" };
|
|
||||||
locale.value = "en";
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
locale,
|
|
||||||
usename,
|
|
||||||
pureApp,
|
|
||||||
favicon,
|
|
||||||
logout,
|
|
||||||
onPanel,
|
|
||||||
translationCh,
|
|
||||||
translationEn,
|
|
||||||
toggleSideBar,
|
|
||||||
deviceDetection
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.navbar {
|
.navbar {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -190,7 +153,7 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.iconinternationality {
|
.globalization {
|
||||||
height: 48px;
|
height: 48px;
|
||||||
width: 40px;
|
width: 40px;
|
||||||
padding: 11px;
|
padding: 11px;
|
||||||
|
@ -1,3 +1,114 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import {
|
||||||
|
computed,
|
||||||
|
unref,
|
||||||
|
watch,
|
||||||
|
nextTick,
|
||||||
|
onMounted,
|
||||||
|
getCurrentInstance
|
||||||
|
} from "vue";
|
||||||
|
import { useI18n } from "vue-i18n";
|
||||||
|
import settings from "/@/settings";
|
||||||
|
import { emitter } from "/@/utils/mitt";
|
||||||
|
import { templateRef } from "@vueuse/core";
|
||||||
|
import SidebarItem from "./sidebarItem.vue";
|
||||||
|
import { algorithm } from "/@/utils/algorithm";
|
||||||
|
import screenfull from "../screenfull/index.vue";
|
||||||
|
import { useRoute, useRouter } from "vue-router";
|
||||||
|
import { storageSession } from "/@/utils/storage";
|
||||||
|
import { deviceDetection } from "/@/utils/deviceDetection";
|
||||||
|
import globalization from "/@/assets/svg/globalization.svg";
|
||||||
|
import { usePermissionStoreHook } from "/@/store/modules/permission";
|
||||||
|
|
||||||
|
const instance =
|
||||||
|
getCurrentInstance().appContext.config.globalProperties.$storage;
|
||||||
|
const menuRef = templateRef<ElRef | null>("menu", null);
|
||||||
|
const routeStore = usePermissionStoreHook();
|
||||||
|
const route = useRoute();
|
||||||
|
const router = useRouter();
|
||||||
|
const routers = useRouter().options.routes;
|
||||||
|
let usename = storageSession.getItem("info")?.username;
|
||||||
|
const { locale, t } = useI18n();
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => locale.value,
|
||||||
|
() => {
|
||||||
|
//@ts-ignore
|
||||||
|
// 动态title
|
||||||
|
document.title = t(unref(route.meta.title));
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 退出登录
|
||||||
|
const logout = (): void => {
|
||||||
|
storageSession.removeItem("info");
|
||||||
|
router.push("/login");
|
||||||
|
};
|
||||||
|
|
||||||
|
function onPanel() {
|
||||||
|
emitter.emit("openPanel");
|
||||||
|
}
|
||||||
|
|
||||||
|
const activeMenu = computed(() => {
|
||||||
|
const { meta, path } = route;
|
||||||
|
if (meta.activeMenu) {
|
||||||
|
return meta.activeMenu;
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
});
|
||||||
|
|
||||||
|
const menuSelect = (indexPath: string): void => {
|
||||||
|
let parentPath = "";
|
||||||
|
let parentPathIndex = indexPath.lastIndexOf("/");
|
||||||
|
if (parentPathIndex > 0) {
|
||||||
|
parentPath = indexPath.slice(0, parentPathIndex);
|
||||||
|
}
|
||||||
|
// 找到当前路由的信息
|
||||||
|
function findCurrentRoute(routes) {
|
||||||
|
return routes.map(item => {
|
||||||
|
if (item.path === indexPath) {
|
||||||
|
// 切换左侧菜单 通知标签页
|
||||||
|
emitter.emit("changLayoutRoute", {
|
||||||
|
indexPath,
|
||||||
|
parentPath
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (item.children) findCurrentRoute(item.children);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
findCurrentRoute(algorithm.increaseIndexes(routers));
|
||||||
|
};
|
||||||
|
|
||||||
|
function backHome() {
|
||||||
|
router.push("/welcome");
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleResize() {
|
||||||
|
menuRef.value.handleResize();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 简体中文
|
||||||
|
function translationCh() {
|
||||||
|
instance.locale = { locale: "zh" };
|
||||||
|
locale.value = "zh";
|
||||||
|
handleResize();
|
||||||
|
}
|
||||||
|
|
||||||
|
// English
|
||||||
|
function translationEn() {
|
||||||
|
instance.locale = { locale: "en" };
|
||||||
|
locale.value = "en";
|
||||||
|
handleResize();
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
nextTick(() => {
|
||||||
|
handleResize();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="horizontal-header">
|
<div class="horizontal-header">
|
||||||
<div class="horizontal-header-left" @click="backHome">
|
<div class="horizontal-header-left" @click="backHome">
|
||||||
@ -25,7 +136,7 @@
|
|||||||
<screenfull v-show="!deviceDetection()" />
|
<screenfull v-show="!deviceDetection()" />
|
||||||
<!-- 国际化 -->
|
<!-- 国际化 -->
|
||||||
<el-dropdown trigger="click">
|
<el-dropdown trigger="click">
|
||||||
<iconinternationality />
|
<globalization />
|
||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
<el-dropdown-menu class="translation">
|
<el-dropdown-menu class="translation">
|
||||||
<el-dropdown-item
|
<el-dropdown-item
|
||||||
@ -72,177 +183,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import {
|
|
||||||
computed,
|
|
||||||
defineComponent,
|
|
||||||
unref,
|
|
||||||
watch,
|
|
||||||
nextTick,
|
|
||||||
onMounted,
|
|
||||||
getCurrentInstance
|
|
||||||
} from "vue";
|
|
||||||
import { useI18n } from "vue-i18n";
|
|
||||||
import settings from "/@/settings";
|
|
||||||
import { emitter } from "/@/utils/mitt";
|
|
||||||
import { templateRef } from "@vueuse/core";
|
|
||||||
import SidebarItem from "./sidebarItem.vue";
|
|
||||||
import { algorithm } from "/@/utils/algorithm";
|
|
||||||
import screenfull from "../screenfull/index.vue";
|
|
||||||
import { useRoute, useRouter } from "vue-router";
|
|
||||||
import { storageSession } from "/@/utils/storage";
|
|
||||||
import { deviceDetection } from "/@/utils/deviceDetection";
|
|
||||||
import { usePermissionStoreHook } from "/@/store/modules/permission";
|
|
||||||
import iconinternationality from "/@/assets/svg/iconinternationality.svg";
|
|
||||||
|
|
||||||
let routerArrays: Array<object> = [
|
|
||||||
{
|
|
||||||
path: "/welcome",
|
|
||||||
parentPath: "/",
|
|
||||||
meta: {
|
|
||||||
title: "message.hshome",
|
|
||||||
icon: "el-icon-s-home",
|
|
||||||
showLink: true,
|
|
||||||
savedPosition: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
export default defineComponent({
|
|
||||||
name: "sidebar",
|
|
||||||
components: { SidebarItem, screenfull, iconinternationality },
|
|
||||||
// @ts-ignore
|
|
||||||
computed: {
|
|
||||||
// eslint-disable-next-line vue/return-in-computed-property
|
|
||||||
currentLocale() {
|
|
||||||
if (
|
|
||||||
!this.$storage.routesInStorage ||
|
|
||||||
this.$storage.routesInStorage.length === 0
|
|
||||||
) {
|
|
||||||
// eslint-disable-next-line vue/no-side-effects-in-computed-properties
|
|
||||||
this.$storage.routesInStorage = routerArrays;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.$storage.locale) {
|
|
||||||
// eslint-disable-next-line
|
|
||||||
this.$storage.locale = { locale: "zh" };
|
|
||||||
useI18n().locale.value = "zh";
|
|
||||||
}
|
|
||||||
switch (this.$storage.locale?.locale) {
|
|
||||||
case "zh":
|
|
||||||
return true;
|
|
||||||
case "en":
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
setup() {
|
|
||||||
const instance =
|
|
||||||
getCurrentInstance().appContext.config.globalProperties.$storage;
|
|
||||||
const menuRef = templateRef<ElRef | null>("menu", null);
|
|
||||||
|
|
||||||
const routeStore = usePermissionStoreHook();
|
|
||||||
const route = useRoute();
|
|
||||||
const router = useRouter();
|
|
||||||
const routers = useRouter().options.routes;
|
|
||||||
let usename = storageSession.getItem("info")?.username;
|
|
||||||
const { locale, t } = useI18n();
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => locale.value,
|
|
||||||
() => {
|
|
||||||
//@ts-ignore
|
|
||||||
// 动态title
|
|
||||||
document.title = t(unref(route.meta.title));
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// 退出登录
|
|
||||||
const logout = (): void => {
|
|
||||||
storageSession.removeItem("info");
|
|
||||||
router.push("/login");
|
|
||||||
};
|
|
||||||
|
|
||||||
function onPanel() {
|
|
||||||
emitter.emit("openPanel");
|
|
||||||
}
|
|
||||||
|
|
||||||
const activeMenu = computed(() => {
|
|
||||||
const { meta, path } = route;
|
|
||||||
if (meta.activeMenu) {
|
|
||||||
return meta.activeMenu;
|
|
||||||
}
|
|
||||||
return path;
|
|
||||||
});
|
|
||||||
|
|
||||||
const menuSelect = (indexPath: string): void => {
|
|
||||||
let parentPath = "";
|
|
||||||
let parentPathIndex = indexPath.lastIndexOf("/");
|
|
||||||
if (parentPathIndex > 0) {
|
|
||||||
parentPath = indexPath.slice(0, parentPathIndex);
|
|
||||||
}
|
|
||||||
// 找到当前路由的信息
|
|
||||||
function findCurrentRoute(routes) {
|
|
||||||
return routes.map(item => {
|
|
||||||
if (item.path === indexPath) {
|
|
||||||
// 切换左侧菜单 通知标签页
|
|
||||||
emitter.emit("changLayoutRoute", {
|
|
||||||
indexPath,
|
|
||||||
parentPath
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
if (item.children) findCurrentRoute(item.children);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
findCurrentRoute(algorithm.increaseIndexes(routers));
|
|
||||||
};
|
|
||||||
|
|
||||||
function backHome() {
|
|
||||||
router.push("/welcome");
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleResize() {
|
|
||||||
menuRef.value.handleResize();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 简体中文
|
|
||||||
function translationCh() {
|
|
||||||
instance.locale = { locale: "zh" };
|
|
||||||
locale.value = "zh";
|
|
||||||
handleResize();
|
|
||||||
}
|
|
||||||
|
|
||||||
// English
|
|
||||||
function translationEn() {
|
|
||||||
instance.locale = { locale: "en" };
|
|
||||||
locale.value = "en";
|
|
||||||
handleResize();
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
nextTick(() => {
|
|
||||||
handleResize();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
locale,
|
|
||||||
usename,
|
|
||||||
settings,
|
|
||||||
routeStore,
|
|
||||||
activeMenu,
|
|
||||||
logout,
|
|
||||||
onPanel,
|
|
||||||
backHome,
|
|
||||||
menuSelect,
|
|
||||||
translationCh,
|
|
||||||
translationEn,
|
|
||||||
deviceDetection
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.translation {
|
.translation {
|
||||||
.el-dropdown-menu__item {
|
.el-dropdown-menu__item {
|
||||||
|
@ -1,3 +1,61 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import Logo from "./logo.vue";
|
||||||
|
import { emitter } from "/@/utils/mitt";
|
||||||
|
import SidebarItem from "./sidebarItem.vue";
|
||||||
|
import { algorithm } from "/@/utils/algorithm";
|
||||||
|
import { storageLocal } from "/@/utils/storage";
|
||||||
|
import { useRoute, useRouter } from "vue-router";
|
||||||
|
import { computed, ref, onBeforeMount } from "vue";
|
||||||
|
import { useAppStoreHook } from "/@/store/modules/app";
|
||||||
|
import { usePermissionStoreHook } from "/@/store/modules/permission";
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
|
const pureApp = useAppStoreHook();
|
||||||
|
const router = useRouter().options.routes;
|
||||||
|
const routeStore = usePermissionStoreHook();
|
||||||
|
const showLogo = ref(storageLocal.getItem("logoVal") || "1");
|
||||||
|
const isCollapse = computed(() => {
|
||||||
|
return !pureApp.getSidebarStatus;
|
||||||
|
});
|
||||||
|
const activeMenu = computed(() => {
|
||||||
|
const { meta, path } = route;
|
||||||
|
if (meta.activeMenu) {
|
||||||
|
return meta.activeMenu;
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
});
|
||||||
|
|
||||||
|
const menuSelect = (indexPath: string): void => {
|
||||||
|
let parentPath = "";
|
||||||
|
let parentPathIndex = indexPath.lastIndexOf("/");
|
||||||
|
if (parentPathIndex > 0) {
|
||||||
|
parentPath = indexPath.slice(0, parentPathIndex);
|
||||||
|
}
|
||||||
|
// 找到当前路由的信息
|
||||||
|
// eslint-disable-next-line no-inner-declarations
|
||||||
|
function findCurrentRoute(routes) {
|
||||||
|
return routes.map(item => {
|
||||||
|
if (item.path === indexPath) {
|
||||||
|
// 切换左侧菜单 通知标签页
|
||||||
|
emitter.emit("changLayoutRoute", {
|
||||||
|
indexPath,
|
||||||
|
parentPath
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (item.children) findCurrentRoute(item.children);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
findCurrentRoute(algorithm.increaseIndexes(router));
|
||||||
|
};
|
||||||
|
|
||||||
|
onBeforeMount(() => {
|
||||||
|
emitter.on("logoChange", key => {
|
||||||
|
showLogo.value = key;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div :class="['sidebar-container', showLogo ? 'has-logo' : '']">
|
<div :class="['sidebar-container', showLogo ? 'has-logo' : '']">
|
||||||
<Logo v-if="showLogo === '1'" :collapse="isCollapse" />
|
<Logo v-if="showLogo === '1'" :collapse="isCollapse" />
|
||||||
@ -21,77 +79,3 @@
|
|||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import Logo from "./logo.vue";
|
|
||||||
import { emitter } from "/@/utils/mitt";
|
|
||||||
import SidebarItem from "./sidebarItem.vue";
|
|
||||||
import { algorithm } from "/@/utils/algorithm";
|
|
||||||
import { storageLocal } from "/@/utils/storage";
|
|
||||||
import { useRoute, useRouter } from "vue-router";
|
|
||||||
import { useAppStoreHook } from "/@/store/modules/app";
|
|
||||||
import { computed, defineComponent, ref, onBeforeMount } from "vue";
|
|
||||||
import { usePermissionStoreHook } from "/@/store/modules/permission";
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: "sidebar",
|
|
||||||
components: { SidebarItem, Logo },
|
|
||||||
setup() {
|
|
||||||
const routeStore = usePermissionStoreHook();
|
|
||||||
|
|
||||||
const router = useRouter().options.routes;
|
|
||||||
|
|
||||||
const pureApp = useAppStoreHook();
|
|
||||||
|
|
||||||
const route = useRoute();
|
|
||||||
|
|
||||||
const showLogo = ref(storageLocal.getItem("logoVal") || "1");
|
|
||||||
|
|
||||||
const activeMenu = computed(() => {
|
|
||||||
const { meta, path } = route;
|
|
||||||
if (meta.activeMenu) {
|
|
||||||
return meta.activeMenu;
|
|
||||||
}
|
|
||||||
return path;
|
|
||||||
});
|
|
||||||
|
|
||||||
const menuSelect = (indexPath: string): void => {
|
|
||||||
let parentPath = "";
|
|
||||||
let parentPathIndex = indexPath.lastIndexOf("/");
|
|
||||||
if (parentPathIndex > 0) {
|
|
||||||
parentPath = indexPath.slice(0, parentPathIndex);
|
|
||||||
}
|
|
||||||
// 找到当前路由的信息
|
|
||||||
// eslint-disable-next-line no-inner-declarations
|
|
||||||
function findCurrentRoute(routes) {
|
|
||||||
return routes.map(item => {
|
|
||||||
if (item.path === indexPath) {
|
|
||||||
// 切换左侧菜单 通知标签页
|
|
||||||
emitter.emit("changLayoutRoute", {
|
|
||||||
indexPath,
|
|
||||||
parentPath
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
if (item.children) findCurrentRoute(item.children);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
findCurrentRoute(algorithm.increaseIndexes(router));
|
|
||||||
};
|
|
||||||
|
|
||||||
onBeforeMount(() => {
|
|
||||||
emitter.on("logoChange", key => {
|
|
||||||
showLogo.value = key;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
activeMenu,
|
|
||||||
isCollapse: computed(() => !pureApp.getSidebarStatus),
|
|
||||||
menuSelect,
|
|
||||||
showLogo,
|
|
||||||
routeStore
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
@ -1,3 +1,442 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
computed: {
|
||||||
|
dynamicTagList() {
|
||||||
|
return this.$storage.routesInStorage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import {
|
||||||
|
ref,
|
||||||
|
watch,
|
||||||
|
onBeforeMount,
|
||||||
|
unref,
|
||||||
|
nextTick,
|
||||||
|
getCurrentInstance
|
||||||
|
} from "vue";
|
||||||
|
import { RouteConfigs } from "../../types";
|
||||||
|
import { emitter } from "/@/utils/mitt";
|
||||||
|
import { templateRef } from "@vueuse/core";
|
||||||
|
import { storageLocal } from "/@/utils/storage";
|
||||||
|
import { useRoute, useRouter } from "vue-router";
|
||||||
|
import { toggleClass, removeClass, hasClass } from "/@/utils/operate";
|
||||||
|
|
||||||
|
import close from "/@/assets/svg/close.svg";
|
||||||
|
import refresh from "/@/assets/svg/refresh.svg";
|
||||||
|
import closeAll from "/@/assets/svg/close_all.svg";
|
||||||
|
import closeLeft from "/@/assets/svg/close_left.svg";
|
||||||
|
import closeOther from "/@/assets/svg/close_other.svg";
|
||||||
|
import closeRight from "/@/assets/svg/close_right.svg";
|
||||||
|
|
||||||
|
let refreshButton = "refresh-button";
|
||||||
|
const instance = getCurrentInstance();
|
||||||
|
let st: any;
|
||||||
|
const route = useRoute();
|
||||||
|
const router = useRouter();
|
||||||
|
const showTags = ref(storageLocal.getItem("tagsVal") || false);
|
||||||
|
const containerDom = templateRef<HTMLElement | null>("containerDom", null);
|
||||||
|
const activeIndex = ref(-1);
|
||||||
|
let routerArrays: Array<RouteConfigs> = [
|
||||||
|
{
|
||||||
|
path: "/welcome",
|
||||||
|
parentPath: "/",
|
||||||
|
meta: {
|
||||||
|
title: "message.hshome",
|
||||||
|
icon: "el-icon-s-home",
|
||||||
|
showLink: true,
|
||||||
|
savedPosition: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
const tagsViews = ref<ForDataType<undefined>>([
|
||||||
|
{
|
||||||
|
icon: refresh,
|
||||||
|
text: "重新加载",
|
||||||
|
divided: false,
|
||||||
|
disabled: false,
|
||||||
|
show: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: close,
|
||||||
|
text: "关闭当前标签页",
|
||||||
|
divided: false,
|
||||||
|
disabled: routerArrays.length > 1 ? false : true,
|
||||||
|
show: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: closeLeft,
|
||||||
|
text: "关闭左侧标签页",
|
||||||
|
divided: true,
|
||||||
|
disabled: routerArrays.length > 1 ? false : true,
|
||||||
|
show: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: closeRight,
|
||||||
|
text: "关闭右侧标签页",
|
||||||
|
divided: false,
|
||||||
|
disabled: routerArrays.length > 1 ? false : true,
|
||||||
|
show: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: closeOther,
|
||||||
|
text: "关闭其他标签页",
|
||||||
|
divided: true,
|
||||||
|
disabled: routerArrays.length > 2 ? false : true,
|
||||||
|
show: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: closeAll,
|
||||||
|
text: "关闭全部标签页",
|
||||||
|
divided: false,
|
||||||
|
disabled: routerArrays.length > 1 ? false : true,
|
||||||
|
show: true
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 显示模式,默认灵动模式显示
|
||||||
|
const showModel = ref(storageLocal.getItem("showModel") || "smart");
|
||||||
|
if (!showModel.value) {
|
||||||
|
storageLocal.setItem("showModel", "card");
|
||||||
|
}
|
||||||
|
|
||||||
|
let visible = ref(false);
|
||||||
|
let buttonLeft = ref(0);
|
||||||
|
let buttonTop = ref(0);
|
||||||
|
|
||||||
|
// 当前右键选中的路由信息
|
||||||
|
let currentSelect = ref({});
|
||||||
|
|
||||||
|
function dynamicRouteTag(value: string, parentPath: string): void {
|
||||||
|
const hasValue = st.routesInStorage.some((item: any) => {
|
||||||
|
return item.path === value;
|
||||||
|
});
|
||||||
|
|
||||||
|
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,
|
||||||
|
parentPath: `/${parentPath.split("/")[1]}`,
|
||||||
|
meta: arrItem.meta
|
||||||
|
});
|
||||||
|
st.routesInStorage = routerArrays;
|
||||||
|
} else {
|
||||||
|
if (arrItem.children && arrItem.children.length > 0) {
|
||||||
|
concatPath(arrItem.children, value, parentPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
concatPath(router.options.routes, value, parentPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重新加载
|
||||||
|
function onFresh() {
|
||||||
|
toggleClass(true, refreshButton, document.querySelector(".rotate"));
|
||||||
|
const { fullPath } = unref(route);
|
||||||
|
router.replace({
|
||||||
|
path: "/redirect" + fullPath
|
||||||
|
});
|
||||||
|
setTimeout(() => {
|
||||||
|
removeClass(document.querySelector(".rotate"), refreshButton);
|
||||||
|
}, 600);
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteDynamicTag(obj: any, current: any, tag?: string) {
|
||||||
|
let valueIndex: number = routerArrays.findIndex((item: any) => {
|
||||||
|
return item.path === obj.path;
|
||||||
|
});
|
||||||
|
|
||||||
|
const spliceRoute = (start?: number, end?: number, other?: boolean): void => {
|
||||||
|
if (other) {
|
||||||
|
st.routesInStorage = [
|
||||||
|
{
|
||||||
|
path: "/welcome",
|
||||||
|
parentPath: "/",
|
||||||
|
meta: {
|
||||||
|
title: "message.hshome",
|
||||||
|
icon: "el-icon-s-home",
|
||||||
|
showLink: true,
|
||||||
|
savedPosition: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
obj
|
||||||
|
];
|
||||||
|
routerArrays = st.routesInStorage;
|
||||||
|
} else {
|
||||||
|
routerArrays.splice(start, end);
|
||||||
|
st.routesInStorage = routerArrays;
|
||||||
|
}
|
||||||
|
router.push(obj.path);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (tag === "other") {
|
||||||
|
spliceRoute(1, 1, true);
|
||||||
|
} else if (tag === "left") {
|
||||||
|
spliceRoute(1, valueIndex - 1);
|
||||||
|
} else if (tag === "right") {
|
||||||
|
spliceRoute(valueIndex + 1, routerArrays.length);
|
||||||
|
} else {
|
||||||
|
// 从当前匹配到的路径中删除
|
||||||
|
spliceRoute(valueIndex, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current === obj.path) {
|
||||||
|
// 如果删除当前激活tag就自动切换到最后一个tag
|
||||||
|
let newRoute: any = routerArrays.slice(-1);
|
||||||
|
nextTick(() => {
|
||||||
|
router.push({
|
||||||
|
path: newRoute[0].path
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteMenu(item, tag?: string) {
|
||||||
|
deleteDynamicTag(item, item.path, tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onClickDrop(key, item, selectRoute?: RouteConfigs) {
|
||||||
|
if (item && item.disabled) return;
|
||||||
|
// 当前路由信息
|
||||||
|
switch (key) {
|
||||||
|
case 0:
|
||||||
|
// 重新加载
|
||||||
|
onFresh();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
// 关闭当前标签页
|
||||||
|
selectRoute
|
||||||
|
? deleteMenu({ path: selectRoute.path, meta: selectRoute.meta })
|
||||||
|
: deleteMenu({ path: route.path, meta: route.meta });
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
// 关闭左侧标签页
|
||||||
|
selectRoute
|
||||||
|
? deleteMenu(
|
||||||
|
{
|
||||||
|
path: selectRoute.path,
|
||||||
|
meta: selectRoute.meta
|
||||||
|
},
|
||||||
|
"left"
|
||||||
|
)
|
||||||
|
: deleteMenu({ path: route.path, meta: route.meta }, "left");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
// 关闭右侧标签页
|
||||||
|
selectRoute
|
||||||
|
? deleteMenu(
|
||||||
|
{
|
||||||
|
path: selectRoute.path,
|
||||||
|
meta: selectRoute.meta
|
||||||
|
},
|
||||||
|
"right"
|
||||||
|
)
|
||||||
|
: deleteMenu({ path: route.path, meta: route.meta }, "right");
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
// 关闭其他标签页
|
||||||
|
selectRoute
|
||||||
|
? deleteMenu(
|
||||||
|
{
|
||||||
|
path: selectRoute.path,
|
||||||
|
meta: selectRoute.meta
|
||||||
|
},
|
||||||
|
"other"
|
||||||
|
)
|
||||||
|
: deleteMenu({ path: route.path, meta: route.meta }, "other");
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
// 关闭全部标签页
|
||||||
|
routerArrays.splice(1, routerArrays.length);
|
||||||
|
st.routesInStorage = routerArrays;
|
||||||
|
router.push("/welcome");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
showMenuModel(route.fullPath);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 触发右键中菜单的点击事件
|
||||||
|
function selectTag(key, item) {
|
||||||
|
onClickDrop(key, item, currentSelect.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeMenu() {
|
||||||
|
visible.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function showMenus(value: Boolean) {
|
||||||
|
Array.of(1, 2, 3, 4, 5).forEach(v => {
|
||||||
|
tagsViews.value[v].show = value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function disabledMenus(value: Boolean) {
|
||||||
|
Array.of(1, 2, 3, 4, 5).forEach(v => {
|
||||||
|
tagsViews.value[v].disabled = value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查当前右键的菜单两边是否存在别的菜单,如果左侧的菜单是首页,则不显示关闭左侧标签页,如果右侧没有菜单,则不显示关闭右侧标签页
|
||||||
|
function showMenuModel(currentPath: string, refresh = false) {
|
||||||
|
let allRoute = unref(st.routesInStorage);
|
||||||
|
let routeLength = unref(st.routesInStorage).length;
|
||||||
|
// currentIndex为1时,左侧的菜单是首页,则不显示关闭左侧标签页
|
||||||
|
let currentIndex = allRoute.findIndex(v => v.path === currentPath);
|
||||||
|
// 如果currentIndex等于routeLength-1,右侧没有菜单,则不显示关闭右侧标签页
|
||||||
|
showMenus(true);
|
||||||
|
|
||||||
|
if (refresh) {
|
||||||
|
tagsViews.value[0].show = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentIndex === 1 && routeLength !== 2) {
|
||||||
|
// 左侧的菜单是首页,右侧存在别的菜单
|
||||||
|
tagsViews.value[2].show = false;
|
||||||
|
Array.of(1, 3, 4, 5).forEach(v => {
|
||||||
|
tagsViews.value[v].disabled = false;
|
||||||
|
});
|
||||||
|
tagsViews.value[2].disabled = true;
|
||||||
|
} else if (currentIndex === 1 && routeLength === 2) {
|
||||||
|
disabledMenus(false);
|
||||||
|
// 左侧的菜单是首页,右侧不存在别的菜单
|
||||||
|
Array.of(2, 3, 4).forEach(v => {
|
||||||
|
tagsViews.value[v].show = false;
|
||||||
|
tagsViews.value[v].disabled = true;
|
||||||
|
});
|
||||||
|
} else if (routeLength - 1 === currentIndex && currentIndex !== 0) {
|
||||||
|
// 当前路由是所有路由中的最后一个
|
||||||
|
tagsViews.value[3].show = false;
|
||||||
|
Array.of(1, 2, 4, 5).forEach(v => {
|
||||||
|
tagsViews.value[v].disabled = false;
|
||||||
|
});
|
||||||
|
tagsViews.value[3].disabled = true;
|
||||||
|
} else if (currentIndex === 0) {
|
||||||
|
// 当前路由为首页
|
||||||
|
disabledMenus(true);
|
||||||
|
} else {
|
||||||
|
disabledMenus(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function openMenu(tag, e) {
|
||||||
|
closeMenu();
|
||||||
|
if (tag.path === "/welcome") {
|
||||||
|
// 右键菜单为首页,只显示刷新
|
||||||
|
showMenus(false);
|
||||||
|
tagsViews.value[0].show = true;
|
||||||
|
} else if (route.path !== tag.path) {
|
||||||
|
// 右键菜单不匹配当前路由,隐藏刷新
|
||||||
|
tagsViews.value[0].show = false;
|
||||||
|
showMenuModel(tag.path);
|
||||||
|
// eslint-disable-next-line no-dupe-else-if
|
||||||
|
} else if (st.routesInStorage.length === 2 && route.path !== tag.path) {
|
||||||
|
showMenus(true);
|
||||||
|
// 只有两个标签时不显示关闭其他标签页
|
||||||
|
tagsViews.value[4].show = false;
|
||||||
|
} else if (route.path === tag.path) {
|
||||||
|
// 右键当前激活的菜单
|
||||||
|
showMenuModel(tag.path, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
currentSelect.value = tag;
|
||||||
|
const menuMinWidth = 105;
|
||||||
|
const offsetLeft = unref(containerDom).getBoundingClientRect().left;
|
||||||
|
const offsetWidth = unref(containerDom).offsetWidth;
|
||||||
|
const maxLeft = offsetWidth - menuMinWidth;
|
||||||
|
const left = e.clientX - offsetLeft + 5;
|
||||||
|
if (left > maxLeft) {
|
||||||
|
buttonLeft.value = maxLeft;
|
||||||
|
} else {
|
||||||
|
buttonLeft.value = left;
|
||||||
|
}
|
||||||
|
buttonTop.value = e.clientY + 10;
|
||||||
|
setTimeout(() => {
|
||||||
|
visible.value = true;
|
||||||
|
}, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 触发tags标签切换
|
||||||
|
function tagOnClick(item) {
|
||||||
|
showMenuModel(item.path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 鼠标移入
|
||||||
|
function onMouseenter(item, index) {
|
||||||
|
if (index) activeIndex.value = index;
|
||||||
|
if (unref(showModel) === "smart") {
|
||||||
|
if (hasClass(instance.refs["schedule" + index], "schedule-active")) return;
|
||||||
|
toggleClass(true, "schedule-in", instance.refs["schedule" + index]);
|
||||||
|
toggleClass(false, "schedule-out", instance.refs["schedule" + index]);
|
||||||
|
} else {
|
||||||
|
if (hasClass(instance.refs["dynamic" + index], "card-active")) return;
|
||||||
|
toggleClass(true, "card-in", instance.refs["dynamic" + index]);
|
||||||
|
toggleClass(false, "card-out", instance.refs["dynamic" + index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 鼠标移出
|
||||||
|
function onMouseleave(item, index) {
|
||||||
|
activeIndex.value = -1;
|
||||||
|
if (unref(showModel) === "smart") {
|
||||||
|
if (hasClass(instance.refs["schedule" + index], "schedule-active")) return;
|
||||||
|
toggleClass(false, "schedule-in", instance.refs["schedule" + index]);
|
||||||
|
toggleClass(true, "schedule-out", instance.refs["schedule" + index]);
|
||||||
|
} else {
|
||||||
|
if (hasClass(instance.refs["dynamic" + index], "card-active")) return;
|
||||||
|
toggleClass(false, "card-in", instance.refs["dynamic" + index]);
|
||||||
|
toggleClass(true, "card-out", instance.refs["dynamic" + index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => visible.value,
|
||||||
|
val => {
|
||||||
|
if (val) {
|
||||||
|
document.body.addEventListener("click", closeMenu);
|
||||||
|
} else {
|
||||||
|
document.body.removeEventListener("click", closeMenu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
onBeforeMount(() => {
|
||||||
|
if (!instance) return;
|
||||||
|
st = instance.appContext.app.config.globalProperties.$storage;
|
||||||
|
routerArrays = st.routesInStorage ?? routerArrays;
|
||||||
|
|
||||||
|
// 根据当前路由初始化操作标签页的禁用状态
|
||||||
|
showMenuModel(route.fullPath);
|
||||||
|
|
||||||
|
// 触发隐藏标签页
|
||||||
|
emitter.on("tagViewsChange", key => {
|
||||||
|
if (unref(showTags) === key) return;
|
||||||
|
showTags.value = key;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 改变标签风格
|
||||||
|
emitter.on("tagViewsShowModel", key => {
|
||||||
|
showModel.value = key;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 接收侧边栏切换传递过来的参数
|
||||||
|
emitter.on("changLayoutRoute", ({ indexPath, parentPath }) => {
|
||||||
|
dynamicRouteTag(indexPath, parentPath);
|
||||||
|
setTimeout(() => {
|
||||||
|
showMenuModel(indexPath);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div ref="containerDom" class="tags-view" v-if="!showTags">
|
<div ref="containerDom" class="tags-view" v-if="!showTags">
|
||||||
<el-scrollbar wrap-class="scrollbar-wrapper" class="scroll-container">
|
<el-scrollbar wrap-class="scrollbar-wrapper" class="scroll-container">
|
||||||
@ -87,479 +526,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import {
|
|
||||||
ref,
|
|
||||||
watch,
|
|
||||||
onBeforeMount,
|
|
||||||
unref,
|
|
||||||
nextTick,
|
|
||||||
getCurrentInstance
|
|
||||||
} from "vue";
|
|
||||||
import { useRoute, useRouter } from "vue-router";
|
|
||||||
import { storageLocal } from "/@/utils/storage";
|
|
||||||
import { emitter } from "/@/utils/mitt";
|
|
||||||
import { toggleClass, removeClass, hasClass } from "/@/utils/operate";
|
|
||||||
import { templateRef } from "@vueuse/core";
|
|
||||||
import closeOther from "/@/assets/svg/close_other.svg";
|
|
||||||
import closeLeft from "/@/assets/svg/close_left.svg";
|
|
||||||
import closeRight from "/@/assets/svg/close_right.svg";
|
|
||||||
import close from "/@/assets/svg/close.svg";
|
|
||||||
import refresh from "/@/assets/svg/refresh.svg";
|
|
||||||
import closeAll from "/@/assets/svg/close_all.svg";
|
|
||||||
|
|
||||||
let refreshButton = "refresh-button";
|
|
||||||
let routerArrays: Array<object> = [
|
|
||||||
{
|
|
||||||
path: "/welcome",
|
|
||||||
parentPath: "/",
|
|
||||||
meta: {
|
|
||||||
title: "message.hshome",
|
|
||||||
icon: "el-icon-s-home",
|
|
||||||
showLink: true,
|
|
||||||
savedPosition: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "tag",
|
|
||||||
components: {
|
|
||||||
closeOther,
|
|
||||||
closeLeft,
|
|
||||||
closeRight,
|
|
||||||
close,
|
|
||||||
refresh,
|
|
||||||
closeAll
|
|
||||||
},
|
|
||||||
// @ts-ignore
|
|
||||||
computed: {
|
|
||||||
dynamicTagList() {
|
|
||||||
return this.$storage.routesInStorage;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
setup() {
|
|
||||||
const instance = getCurrentInstance();
|
|
||||||
let st: any;
|
|
||||||
const route = useRoute();
|
|
||||||
const router = useRouter();
|
|
||||||
const showTags = ref(storageLocal.getItem("tagsVal") || false);
|
|
||||||
const containerDom = templateRef<HTMLElement | null>("containerDom", null);
|
|
||||||
const activeIndex = ref(-1);
|
|
||||||
const tagsViews = ref([
|
|
||||||
{
|
|
||||||
icon: "refresh",
|
|
||||||
text: "重新加载",
|
|
||||||
divided: false,
|
|
||||||
disabled: false,
|
|
||||||
show: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: "close",
|
|
||||||
text: "关闭当前标签页",
|
|
||||||
divided: false,
|
|
||||||
disabled: routerArrays.length > 1 ? false : true,
|
|
||||||
show: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: "closeLeft",
|
|
||||||
text: "关闭左侧标签页",
|
|
||||||
divided: true,
|
|
||||||
disabled: routerArrays.length > 1 ? false : true,
|
|
||||||
show: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: "closeRight",
|
|
||||||
text: "关闭右侧标签页",
|
|
||||||
divided: false,
|
|
||||||
disabled: routerArrays.length > 1 ? false : true,
|
|
||||||
show: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: "closeOther",
|
|
||||||
text: "关闭其他标签页",
|
|
||||||
divided: true,
|
|
||||||
disabled: routerArrays.length > 2 ? false : true,
|
|
||||||
show: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: "closeAll",
|
|
||||||
text: "关闭全部标签页",
|
|
||||||
divided: false,
|
|
||||||
disabled: routerArrays.length > 1 ? false : true,
|
|
||||||
show: true
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
|
|
||||||
// 显示模式,默认灵动模式显示
|
|
||||||
const showModel = ref(storageLocal.getItem("showModel") || "smart");
|
|
||||||
if (!showModel.value) {
|
|
||||||
storageLocal.setItem("showModel", "card");
|
|
||||||
}
|
|
||||||
|
|
||||||
let visible = ref(false);
|
|
||||||
let buttonLeft = ref(0);
|
|
||||||
let buttonTop = ref(0);
|
|
||||||
|
|
||||||
// 当前右键选中的路由信息
|
|
||||||
let currentSelect = ref({});
|
|
||||||
|
|
||||||
function dynamicRouteTag(value: string, parentPath: string): void {
|
|
||||||
const hasValue = st.routesInStorage.some((item: any) => {
|
|
||||||
return item.path === value;
|
|
||||||
});
|
|
||||||
|
|
||||||
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,
|
|
||||||
parentPath: `/${parentPath.split("/")[1]}`,
|
|
||||||
meta: arrItem.meta
|
|
||||||
});
|
|
||||||
st.routesInStorage = routerArrays;
|
|
||||||
} else {
|
|
||||||
if (arrItem.children && arrItem.children.length > 0) {
|
|
||||||
concatPath(arrItem.children, value, parentPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
concatPath(router.options.routes, value, parentPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 重新加载
|
|
||||||
function onFresh() {
|
|
||||||
toggleClass(true, refreshButton, document.querySelector(".rotate"));
|
|
||||||
const { fullPath } = unref(route);
|
|
||||||
router.replace({
|
|
||||||
path: "/redirect" + fullPath
|
|
||||||
});
|
|
||||||
setTimeout(() => {
|
|
||||||
removeClass(document.querySelector(".rotate"), refreshButton);
|
|
||||||
}, 600);
|
|
||||||
}
|
|
||||||
|
|
||||||
function deleteDynamicTag(obj: any, current: any, tag?: string) {
|
|
||||||
let valueIndex: number = routerArrays.findIndex((item: any) => {
|
|
||||||
return item.path === obj.path;
|
|
||||||
});
|
|
||||||
|
|
||||||
const spliceRoute = (
|
|
||||||
start?: number,
|
|
||||||
end?: number,
|
|
||||||
other?: boolean
|
|
||||||
): void => {
|
|
||||||
if (other) {
|
|
||||||
st.routesInStorage = routerArrays = [
|
|
||||||
{
|
|
||||||
path: "/welcome",
|
|
||||||
parentPath: "/",
|
|
||||||
meta: {
|
|
||||||
title: "message.hshome",
|
|
||||||
icon: "el-icon-s-home",
|
|
||||||
showLink: true,
|
|
||||||
savedPosition: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
obj
|
|
||||||
];
|
|
||||||
} else {
|
|
||||||
routerArrays.splice(start, end);
|
|
||||||
st.routesInStorage = routerArrays;
|
|
||||||
}
|
|
||||||
router.push(obj.path);
|
|
||||||
};
|
|
||||||
|
|
||||||
if (tag === "other") {
|
|
||||||
spliceRoute(1, 1, true);
|
|
||||||
} else if (tag === "left") {
|
|
||||||
spliceRoute(1, valueIndex - 1);
|
|
||||||
} else if (tag === "right") {
|
|
||||||
spliceRoute(valueIndex + 1, routerArrays.length);
|
|
||||||
} else {
|
|
||||||
// 从当前匹配到的路径中删除
|
|
||||||
spliceRoute(valueIndex, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (current === obj.path) {
|
|
||||||
// 如果删除当前激活tag就自动切换到最后一个tag
|
|
||||||
let newRoute: any = routerArrays.slice(-1);
|
|
||||||
nextTick(() => {
|
|
||||||
router.push({
|
|
||||||
path: newRoute[0].path
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function deleteMenu(item, tag?: string) {
|
|
||||||
deleteDynamicTag(item, item.path, tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onClickDrop(key, item, selectRoute) {
|
|
||||||
if (item && item.disabled) return;
|
|
||||||
// 当前路由信息
|
|
||||||
switch (key) {
|
|
||||||
case 0:
|
|
||||||
// 重新加载
|
|
||||||
onFresh();
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
// 关闭当前标签页
|
|
||||||
selectRoute
|
|
||||||
? deleteMenu({ path: selectRoute.path, meta: selectRoute.meta })
|
|
||||||
: deleteMenu({ path: route.path, meta: route.meta });
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
// 关闭左侧标签页
|
|
||||||
selectRoute
|
|
||||||
? deleteMenu(
|
|
||||||
{
|
|
||||||
path: selectRoute.path,
|
|
||||||
meta: selectRoute.meta
|
|
||||||
},
|
|
||||||
"left"
|
|
||||||
)
|
|
||||||
: deleteMenu({ path: route.path, meta: route.meta }, "left");
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
// 关闭右侧标签页
|
|
||||||
selectRoute
|
|
||||||
? deleteMenu(
|
|
||||||
{
|
|
||||||
path: selectRoute.path,
|
|
||||||
meta: selectRoute.meta
|
|
||||||
},
|
|
||||||
"right"
|
|
||||||
)
|
|
||||||
: deleteMenu({ path: route.path, meta: route.meta }, "right");
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
// 关闭其他标签页
|
|
||||||
selectRoute
|
|
||||||
? deleteMenu(
|
|
||||||
{
|
|
||||||
path: selectRoute.path,
|
|
||||||
meta: selectRoute.meta
|
|
||||||
},
|
|
||||||
"other"
|
|
||||||
)
|
|
||||||
: deleteMenu({ path: route.path, meta: route.meta }, "other");
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
// 关闭全部标签页
|
|
||||||
routerArrays.splice(1, routerArrays.length);
|
|
||||||
st.routesInStorage = routerArrays;
|
|
||||||
router.push("/welcome");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
setTimeout(() => {
|
|
||||||
showMenuModel(route.fullPath);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 触发右键中菜单的点击事件
|
|
||||||
function selectTag(key, item) {
|
|
||||||
onClickDrop(key, item, currentSelect.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
function closeMenu() {
|
|
||||||
visible.value = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function showMenus(value: Boolean) {
|
|
||||||
Array.of(1, 2, 3, 4, 5).forEach(v => {
|
|
||||||
tagsViews.value[v].show = value;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function disabledMenus(value: Boolean) {
|
|
||||||
Array.of(1, 2, 3, 4, 5).forEach(v => {
|
|
||||||
tagsViews.value[v].disabled = value;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查当前右键的菜单两边是否存在别的菜单,如果左侧的菜单是首页,则不显示关闭左侧标签页,如果右侧没有菜单,则不显示关闭右侧标签页
|
|
||||||
function showMenuModel(currentPath: string, refresh = false) {
|
|
||||||
let allRoute = unref(st.routesInStorage);
|
|
||||||
let routeLength = unref(st.routesInStorage).length;
|
|
||||||
// currentIndex为1时,左侧的菜单是首页,则不显示关闭左侧标签页
|
|
||||||
let currentIndex = allRoute.findIndex(v => v.path === currentPath);
|
|
||||||
// 如果currentIndex等于routeLength-1,右侧没有菜单,则不显示关闭右侧标签页
|
|
||||||
showMenus(true);
|
|
||||||
|
|
||||||
if (refresh) {
|
|
||||||
tagsViews.value[0].show = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentIndex === 1 && routeLength !== 2) {
|
|
||||||
// 左侧的菜单是首页,右侧存在别的菜单
|
|
||||||
tagsViews.value[2].show = false;
|
|
||||||
Array.of(1, 3, 4, 5).forEach(v => {
|
|
||||||
tagsViews.value[v].disabled = false;
|
|
||||||
});
|
|
||||||
tagsViews.value[2].disabled = true;
|
|
||||||
} else if (currentIndex === 1 && routeLength === 2) {
|
|
||||||
disabledMenus(false);
|
|
||||||
// 左侧的菜单是首页,右侧不存在别的菜单
|
|
||||||
Array.of(2, 3, 4).forEach(v => {
|
|
||||||
tagsViews.value[v].show = false;
|
|
||||||
tagsViews.value[v].disabled = true;
|
|
||||||
});
|
|
||||||
} else if (routeLength - 1 === currentIndex && currentIndex !== 0) {
|
|
||||||
// 当前路由是所有路由中的最后一个
|
|
||||||
tagsViews.value[3].show = false;
|
|
||||||
Array.of(1, 2, 4, 5).forEach(v => {
|
|
||||||
tagsViews.value[v].disabled = false;
|
|
||||||
});
|
|
||||||
tagsViews.value[3].disabled = true;
|
|
||||||
} else if (currentIndex === 0) {
|
|
||||||
// 当前路由为首页
|
|
||||||
disabledMenus(true);
|
|
||||||
} else {
|
|
||||||
disabledMenus(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function openMenu(tag, e) {
|
|
||||||
closeMenu();
|
|
||||||
if (tag.path === "/welcome") {
|
|
||||||
// 右键菜单为首页,只显示刷新
|
|
||||||
showMenus(false);
|
|
||||||
tagsViews.value[0].show = true;
|
|
||||||
} else if (route.path !== tag.path) {
|
|
||||||
// 右键菜单不匹配当前路由,隐藏刷新
|
|
||||||
tagsViews.value[0].show = false;
|
|
||||||
showMenuModel(tag.path);
|
|
||||||
// eslint-disable-next-line no-dupe-else-if
|
|
||||||
} else if (st.routesInStorage.length === 2 && route.path !== tag.path) {
|
|
||||||
showMenus(true);
|
|
||||||
// 只有两个标签时不显示关闭其他标签页
|
|
||||||
tagsViews.value[4].show = false;
|
|
||||||
} else if (route.path === tag.path) {
|
|
||||||
// 右键当前激活的菜单
|
|
||||||
showMenuModel(tag.path, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
currentSelect.value = tag;
|
|
||||||
const menuMinWidth = 105;
|
|
||||||
const offsetLeft = unref(containerDom).getBoundingClientRect().left;
|
|
||||||
const offsetWidth = unref(containerDom).offsetWidth;
|
|
||||||
const maxLeft = offsetWidth - menuMinWidth;
|
|
||||||
const left = e.clientX - offsetLeft + 5;
|
|
||||||
if (left > maxLeft) {
|
|
||||||
buttonLeft.value = maxLeft;
|
|
||||||
} else {
|
|
||||||
buttonLeft.value = left;
|
|
||||||
}
|
|
||||||
buttonTop.value = e.clientY + 10;
|
|
||||||
setTimeout(() => {
|
|
||||||
visible.value = true;
|
|
||||||
}, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 触发tags标签切换
|
|
||||||
function tagOnClick(item) {
|
|
||||||
showMenuModel(item.path);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 鼠标移入
|
|
||||||
function onMouseenter(item, index) {
|
|
||||||
if (index) activeIndex.value = index;
|
|
||||||
if (unref(showModel) === "smart") {
|
|
||||||
if (hasClass(instance.refs["schedule" + index], "schedule-active"))
|
|
||||||
return;
|
|
||||||
toggleClass(true, "schedule-in", instance.refs["schedule" + index]);
|
|
||||||
toggleClass(false, "schedule-out", instance.refs["schedule" + index]);
|
|
||||||
} else {
|
|
||||||
if (hasClass(instance.refs["dynamic" + index], "card-active")) return;
|
|
||||||
toggleClass(true, "card-in", instance.refs["dynamic" + index]);
|
|
||||||
toggleClass(false, "card-out", instance.refs["dynamic" + index]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 鼠标移出
|
|
||||||
function onMouseleave(item, index) {
|
|
||||||
activeIndex.value = -1;
|
|
||||||
if (unref(showModel) === "smart") {
|
|
||||||
if (hasClass(instance.refs["schedule" + index], "schedule-active"))
|
|
||||||
return;
|
|
||||||
toggleClass(false, "schedule-in", instance.refs["schedule" + index]);
|
|
||||||
toggleClass(true, "schedule-out", instance.refs["schedule" + index]);
|
|
||||||
} else {
|
|
||||||
if (hasClass(instance.refs["dynamic" + index], "card-active")) return;
|
|
||||||
toggleClass(false, "card-in", instance.refs["dynamic" + index]);
|
|
||||||
toggleClass(true, "card-out", instance.refs["dynamic" + index]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => visible.value,
|
|
||||||
val => {
|
|
||||||
if (val) {
|
|
||||||
document.body.addEventListener("click", closeMenu);
|
|
||||||
} else {
|
|
||||||
document.body.removeEventListener("click", closeMenu);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
onBeforeMount(() => {
|
|
||||||
if (!instance) return;
|
|
||||||
st = instance.appContext.app.config.globalProperties.$storage;
|
|
||||||
routerArrays = st.routesInStorage ?? routerArrays;
|
|
||||||
|
|
||||||
// 根据当前路由初始化操作标签页的禁用状态
|
|
||||||
showMenuModel(route.fullPath);
|
|
||||||
|
|
||||||
// 触发隐藏标签页
|
|
||||||
emitter.on("tagViewsChange", key => {
|
|
||||||
if (unref(showTags) === key) return;
|
|
||||||
showTags.value = key;
|
|
||||||
});
|
|
||||||
|
|
||||||
// 改变标签风格
|
|
||||||
emitter.on("tagViewsShowModel", key => {
|
|
||||||
showModel.value = key;
|
|
||||||
});
|
|
||||||
|
|
||||||
// 接收侧边栏切换传递过来的参数
|
|
||||||
emitter.on("changLayoutRoute", ({ indexPath, parentPath }) => {
|
|
||||||
dynamicRouteTag(indexPath, parentPath);
|
|
||||||
setTimeout(() => {
|
|
||||||
showMenuModel(indexPath);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
deleteMenu,
|
|
||||||
showTags,
|
|
||||||
onFresh,
|
|
||||||
tagsViews,
|
|
||||||
onClickDrop,
|
|
||||||
visible,
|
|
||||||
buttonLeft,
|
|
||||||
buttonTop,
|
|
||||||
openMenu,
|
|
||||||
closeMenu,
|
|
||||||
selectTag,
|
|
||||||
currentSelect,
|
|
||||||
onMouseenter,
|
|
||||||
onMouseleave,
|
|
||||||
tagOnClick,
|
|
||||||
activeIndex,
|
|
||||||
showModel,
|
|
||||||
showMenuModel
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@keyframes scheduleInWidth {
|
@keyframes scheduleInWidth {
|
||||||
from {
|
from {
|
||||||
|
@ -1,16 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
let routerArrays: Array<object> = [
|
import { routerArrays } from "./types";
|
||||||
{
|
|
||||||
path: "/welcome",
|
|
||||||
parentPath: "/",
|
|
||||||
meta: {
|
|
||||||
title: "message.hshome",
|
|
||||||
icon: "el-icon-s-home",
|
|
||||||
showLink: true,
|
|
||||||
savedPosition: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
export default {
|
export default {
|
||||||
computed: {
|
computed: {
|
||||||
layout() {
|
layout() {
|
||||||
@ -204,7 +193,6 @@ onBeforeMount(() => {
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
$sideBarWidth: 210px;
|
|
||||||
@mixin clearfix {
|
@mixin clearfix {
|
||||||
&::after {
|
&::after {
|
||||||
content: "";
|
content: "";
|
||||||
@ -241,7 +229,7 @@ $sideBarWidth: 210px;
|
|||||||
top: 0;
|
top: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
z-index: 9;
|
z-index: 9;
|
||||||
width: calc(100% - #{$sideBarWidth});
|
width: calc(100% - 210px);
|
||||||
transition: width 0.28s;
|
transition: width 0.28s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
23
src/layout/types.ts
Normal file
23
src/layout/types.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
export type RouteConfigs = {
|
||||||
|
path?: string;
|
||||||
|
parentPath?: string;
|
||||||
|
meta?: {
|
||||||
|
title?: string;
|
||||||
|
icon?: string;
|
||||||
|
showLink?: boolean;
|
||||||
|
savedPosition?: boolean;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const routerArrays: Array<RouteConfigs> = [
|
||||||
|
{
|
||||||
|
path: "/welcome",
|
||||||
|
parentPath: "/",
|
||||||
|
meta: {
|
||||||
|
title: "message.hshome",
|
||||||
|
icon: "el-icon-s-home",
|
||||||
|
showLink: true,
|
||||||
|
savedPosition: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
@ -179,7 +179,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.iconinternationality {
|
.globalization {
|
||||||
height: 62px;
|
height: 62px;
|
||||||
width: 40px;
|
width: 40px;
|
||||||
padding: 11px;
|
padding: 11px;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user