Commit 903c29de by ningjihai

顶部菜单

parent b6f46f4e
<template>
<div v-if="!item.hidden">
<div v-if="!item.hidden">
<template v-if="hasOneShowingChild(item.children, item) && (!onlyOneChild.children || onlyOneChild.noShowingChildren) && !item.alwaysShow">
<app-link :to="resolvePath(onlyOneChild.path, onlyOneChild.query)">
<el-menu-item style="height: 80px;" :index="resolvePath(onlyOneChild.path)" @click="pageLuyou(onlyOneChild)">
<el-menu-item
style="height: 80px;"
:index="resolvePath(onlyOneChild.path)"
@click="handleNoChildrenClick(item)"
>
<svg-icon :icon-class="onlyOneChild.meta.icon || (item.meta && item.meta.icon)"/>
<span class="menu-title" style="color: #fff;">{{ onlyOneChild.meta.title }}</span>
</el-menu-item>
</app-link>
</template>
<el-sub-menu style="height: 80px;line-height: 80px;" v-else :index="resolvePath(item.path)" teleported>
<template v-if="item.meta" #title>
<svg-icon :icon-class="item.meta && item.meta.icon" />
<span class="menu-title" style="color: #fff;">{{ item.meta.title }}</span>
</template>
<sidebar-item
v-for="(child, index) in item.children"
:key="child.path + index"
:item="child"
:base-path="resolvePath(child.path)"
/>
</el-sub-menu>
<el-menu-item
v-else
style="height: 80px;"
:index="resolvePath(item.path)"
@click="handleItemClick(item)"
>
<svg-icon :icon-class="item.meta && item.meta.icon" />
<span class="menu-title" style="color: #fff;">{{ item.meta.title }}</span>
</el-menu-item>
</div>
</template>
......@@ -28,6 +29,7 @@
import { isExternal } from '@/utils/validate'
import AppLink from './Link'
import { getNormalPath } from '@/utils/ruoyi'
import { ref } from 'vue'
const props = defineProps({
// route object
......@@ -45,11 +47,36 @@ const props = defineProps({
}
})
const emit = defineEmits(['parent-click','no-children-click'])
const onlyOneChild = ref({})
function handleItemClick(item) {
if (item.children && item.children.length > 0) {
const visibleChildren = item.children.map(child => ({
...child,
fullPath: getNormalPath(props.basePath + '/' + child.path) // 添加完整路径
})).filter(child => !child.hidden)
if (visibleChildren.length > 0) {
emit('parent-click', visibleChildren)
} else {
emit('no-children-click')
}
} else {
emit('no-children-click')
}
pageLuyou(item)
}
function handleNoChildrenClick(item) {
emit('no-children-click')
pageLuyou(item)
}
function pageLuyou(route) {
console.log(route)
console.log('导航到:', route)
}
......@@ -65,12 +92,10 @@ function hasOneShowingChild(children = [], parent) {
return true
})
// When there is only one child router, the child router is displayed by default
if (showingChildren.length === 1) {
return true
}
// Show parent if there are no child router to display
if (showingChildren.length === 0) {
onlyOneChild.value = { ...parent, path: '', noShowingChildren: true }
return true
......@@ -88,16 +113,11 @@ function resolvePath(routePath, routeQuery) {
}
if (routeQuery) {
let query = JSON.parse(routeQuery)
return { path: getNormalPath(props.basePath + '/' + routePath), query: query }
return {
path: getNormalPath(props.basePath + '/' + routePath),
query: query
}
}
return getNormalPath(props.basePath + '/' + routePath)
}
function hasTitle(title){
if (title.length > 5) {
return title
} else {
return ""
}
}
</script>
</script>
\ No newline at end of file
......@@ -9,16 +9,35 @@
:text-color="getMenuTextColor"
:active-text-color="'#fff'"
:unique-opened="false"
:ellipsis="false"
>
<sidebar-item
v-for="(route, index) in menuShowData"
:key="route.id || route.path + index"
:item="route"
:base-path="route.path"
@parent-click="handleParentClick"
@no-children-click="handleNoChildrenClick"
/>
</el-menu>
</el-scrollbar>
<!-- 子菜单容器 -->
<div v-if="submenuItems.length > 0" class="submenu-container">
<div class="submenu-wrapper">
<template v-for="(child, index) in submenuItems" :key="child.path + index">
<div v-if="!child.hidden" class="submenu-item" :class="[child.fullPath === route.fullPath ? 'active-submenu-item' : '']" >
<app-link :to="child.fullPath"> <!-- 使用完整路径 -->
<div class="submenu-link" >
<svg-icon :icon-class="child.meta.icon" />
<span>{{ child.meta.title }}</span>
</div>
</app-link>
</div>
</template>
</div>
</div>
<div class="right-menu">
<!-- 这里可以放用户信息、设置按钮等 -->
<header-search id="header-search" class="right-menu-item" />
......@@ -45,18 +64,22 @@
</template>
<script setup>
import { isExternal } from '@/utils/validate'
import { ElMessageBox } from 'element-plus'
import HeaderSearch from '@/components/HeaderSearch'
import Logo from './Logo'
import SidebarItem from './SidebarItem'
import AppLink from './Link'
import variables from '@/assets/styles/variables.module.scss'
import useAppStore from '@/store/modules/app'
import useSettingsStore from '@/store/modules/settings'
import useUserStore from '@/store/modules/user'
import usePermissionStore from '@/store/modules/permission'
import { computed } from 'vue'
import { ref, computed } from 'vue'
import { getNormalPath } from '@/utils/ruoyi'
import { useRoute } from 'vue-router'
const route = useRoute()
const submenuItems = ref([])
const appStore = useAppStore()
const userStore = useUserStore()
const settingsStore = useSettingsStore()
......@@ -73,6 +96,31 @@ const navType = computed(() => {
return type
})
function handleParentClick(children) {
submenuItems.value = children
}
function handleNoChildrenClick() {
submenuItems.value = []
}
const activeMenuItem = ref(null)
function handleChild(child) {
}
function resolvePath(routePath, routeQuery) {
// 您的路径解析逻辑
if (isExternal(routePath)) {
return routePath
}
if (routeQuery) {
let query = JSON.parse(routeQuery)
return { path: getNormalPath(routePath), query: query }
}
return getNormalPath(routePath)
}
// 菜单显示数据
const menuShowData = computed(() => {
const list = processedRouters.value.filter(item => {
......@@ -168,20 +216,26 @@ function logout() {
display: flex;
align-items: center;
height: var(--navbar-height);
box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.25);
.navbar-logo {
flex-shrink: 0;
// width: vars.$base-sidebar-width;
height: 100%;
height: 80px;
width: 300px;
display: flex;
align-items: center;
justify-content: center;
position: absolute;
top: 0;
left: 0;
}
.scrollbar-wrapper {
margin: 0 300px;
flex: 1;
overflow: hidden;
// padding-right: 83px;
display: flex;
justify-content: center;
:deep(.el-scrollbar__view) {
height: 100%;
......@@ -198,11 +252,43 @@ function logout() {
}
.right-menu {
position: absolute;
top: 0;
right: 0;
height: 80px;
display: flex;
flex-shrink: 0;
padding-right: 15px;
}
align-items: center;
}
}
.submenu-container {
position: absolute;
left: 0;
top: 80px;
width: 100%;
height: 50px;
.submenu-wrapper {
height: 100%;
background: rgba(255, 255, 255, 1);
display: flex;
justify-content: center;
align-items: center;
.submenu-item {
margin-left: 66px;
&:first-child {
margin-left: 0;
}
&:hover {
color: rgba(33, 103, 217, 1);
cursor: pointer;
}
}
.active-submenu-item {
color: rgba(33, 103, 217, 1);
cursor: pointer;
}
}
}
.avatar-container {
margin-right: 0px;
......@@ -237,4 +323,7 @@ function logout() {
}
}
}
</style>
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论