瀏覽代碼

菜单导航记录

ZaiZai 2 年之前
父節點
當前提交
ee12b9080b
共有 2 個文件被更改,包括 197 次插入1 次删除
  1. 2 1
      src/layout/index.vue
  2. 195 0
      src/layout/modules/TopMenuBar.vue

+ 2 - 1
src/layout/index.vue

@@ -27,7 +27,6 @@
             <el-header class="hc-header-view">
                 <div class="hc-header-page-name" id="hc-header-page-name">
                     {{RoutesTitle}}
-                    <input multiple type="file" id="file" @change="handleChange" v-if="userInfo?.user_id == '1541381503819694081'">
                 </div>
                 <div class="hc-header-content">
                     <div class="hc-header-cascader-box">
@@ -39,6 +38,7 @@
                     <UserInfoBar></UserInfoBar>
                 </div>
             </el-header>
+            <TopMenuBar/>
             <el-main class="hc-main-box" id="hc-main-box">
                 <router-view v-slot="{ Component }" v-if="reloadRouter">
                     <transition name="fade-transform">
@@ -60,6 +60,7 @@ import MenuBar from "./modules/MenuBar.vue"
 import HelpInfoBar from "./modules/HelpInfoBar.vue"
 import UserInfoBar from "./modules/UserInfoBar.vue"
 import ConfigBar from "./modules/ConfigBar.vue"
+import TopMenuBar from "./modules/TopMenuBar.vue"
 import {initButtons,initProjectContract} from "~sto/app";
 import NameDark from "~src/assets/logo/name-dark.png";
 import NameWhite from "~src/assets/logo/name-white.png";

+ 195 - 0
src/layout/modules/TopMenuBar.vue

@@ -0,0 +1,195 @@
+<template>
+    <div class="hc-top-menu-bar">
+        <el-scrollbar>
+            <div class="bar-menu-content">
+                <div v-for="(item, index) in barMenuData" class="bar-menu-btn" :class="item.key === barRoutes.key?'cur':''"
+                     @click="barMenuClick(item)" @contextmenu.prevent="barMenuContextMenu($event, item, index)">
+                    <span>{{item.title}}</span>
+                    <div class="bar-close-icon" @click.stop="barMenuCloseClick(item, index)">
+                        <HcIcon name="close"/>
+                    </div>
+                </div>
+            </div>
+        </el-scrollbar>
+
+        <!--右键菜单-->
+        <HcContextMenu ref="contextMenuRef" :datas="menusData" @item-click="handleMenuSelect"/>
+    </div>
+</template>
+
+<script setup>
+import {onMounted, ref, watch} from "vue";
+import {useAppStore} from "~src/store";
+import {useRouter, useRoute} from 'vue-router'
+import {getStoreData, setStoreData} from '~src/utils/storage'
+
+//初始组合式
+const router = useRouter()
+const useRoutes = useRoute()
+const useAppState = useAppStore()
+
+//初始变量
+const barMenuData = ref(getStoreData('bar-menu-datas') || []);
+const barRoutes = ref({key: '', path: '', title: ''});
+
+//渲染完成
+onMounted(() => {
+    const {name, path, meta} = useRoutes
+    console.log(barMenuData.value)
+    barRoutes.value = {path, key: name, title: meta?.title}
+    setBarMenuData()
+})
+
+//监听
+watch(() => [
+    useRoutes?.name,
+    useRoutes?.path,
+    useRoutes?.meta?.title,
+], ([key, path, title]) => {
+    barRoutes.value = {path, key, title}
+    setBarMenuData()
+})
+
+//设置菜单数据
+const setBarMenuData = () => {
+    const {key, path, title} = barRoutes.value
+    if (key !== 'home-index') {
+        const index = barMenuData.value.findIndex(item => item.key === key)
+        if (index === -1) {
+            barMenuData.value.push({path, key: key, title: title})
+        }
+        setStoreData('bar-menu-datas', barMenuData.value)
+    }
+}
+
+//菜单被点击
+const barMenuClick = (item) => {
+    const { key } = barRoutes.value
+    if (key !== item.key) {
+        router.push({name: item.key});
+    }
+}
+
+//鼠标右键菜单
+const contextMenuRef = ref(null);
+const barItem = ref({});
+const barItemIndex = ref(0);
+const menusData = ref([
+    {label: '关闭当前', key: "close"},
+    {label: '关闭所有', key: "all"},
+]);
+const barMenuContextMenu = (event, item, index) => {
+    event.preventDefault();
+    barItem.value = item;
+    barItemIndex.value = index;
+    contextMenuRef.value?.showMenu(event);
+}
+
+//鼠标右键菜单被点击
+const handleMenuSelect = ({key}) => {
+    if (key === 'close') {
+        barMenuCloseClick(barItem.value, barItemIndex.value)
+    } else if (key === 'all') {
+        barMenuData.value = []
+        setStoreData('bar-menu-datas', [])
+        router.push({name: 'home-index'});
+    }
+}
+
+//菜单关闭被点击
+const barMenuCloseClick = (item, index) => {
+    const total = barMenuData.value.length -1;
+    const { key } = barRoutes.value
+    barMenuData.value.splice(index, 1)
+    if (key === item.key) {
+        let items = {};
+        const indexs = barMenuData.value.length -1;
+        if(total > index) {
+            items = barMenuData.value[index]
+        } else if(indexs >= 0) {
+            items = barMenuData.value[indexs]
+        }
+        if (indexs < 0) {
+            setStoreData('bar-menu-datas', barMenuData.value)
+            router.push({name: 'home-index'});
+        } else {
+            barRoutes.value = items
+            setStoreData('bar-menu-datas', barMenuData.value)
+            router.push({name: items.key});
+        }
+    } else {
+        setStoreData('bar-menu-datas', barMenuData.value)
+    }
+}
+</script>
+
+<style lang="scss">
+.hc-top-menu-bar {
+    position: relative;
+    padding: 0 24px 20px;
+    margin-top: -8px;
+    .bar-menu-content {
+        display: flex;
+        position: relative;
+        .bar-menu-btn {
+            position: relative;
+            color: #b3b3b3;
+            padding-left: 10px;
+            padding-right: 6px;
+            height: 32px;
+            font-size: 14px;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            background: #ffffff;
+            border: 1px solid #ffffff;
+            border-radius: 4px;
+            user-select: none;
+            cursor: pointer;
+            white-space: nowrap;
+            transition: background 0.3s, color 0.3s;
+            &:hover:not([class*='cur']) {
+                background: var(--el-color-primary-light-9);
+                color: #838791;
+            }
+            &:active:not([class*='cur']) {
+                background: var(--el-color-primary-light-8);
+                color: #838791;
+            }
+            &.cur {
+                color: #ffffff;
+                cursor: default;
+                background: linear-gradient(to right, var(--el-color-primary-light-5), var(--el-color-primary), var(--el-color-primary-dark-2));
+                background-size: 200%;
+                transition: background-position 0.5s;
+            }
+            .bar-close-icon {
+                height: 30px;
+                width: 18px;
+                display: flex;
+                align-items: center;
+                justify-content: center;
+                margin-left: 6px;
+                font-size: 16px;
+                cursor: pointer;
+                transition: color 0.3s;
+                &:hover {
+                    color: var(--el-color-primary);
+                }
+            }
+        }
+        .bar-menu-btn.cur .bar-close-icon:hover {
+            color: #000000;
+        }
+        .bar-menu-btn + .bar-menu-btn {
+            margin-left: 10px;
+        }
+    }
+    .el-scrollbar__bar.is-horizontal {
+        bottom: -10px;
+    }
+    .el-scrollbar__bar.is-vertical {
+        display: none;
+    }
+}
+</style>