feat: 侧边栏单独模块下使用公共

This commit is contained in:
gaofeihang committed 2025-09-18 00:03:54 +08:00
1 parent f22333f6f5
commit 4f5a69265d
3 files changed
+165

No files matched your search

+108
View File
@@ -0,0 +1,108 @@
<template>
<div class="equipment-bar" v-if="!isCollapsed">
<img src="@/assets/images/equipment/侧边导航栏.png" alt="" />
<div class="equipment-item">
<div v-for="(item, index) in menuItems" :key="index" class="" @click="selectItem(index)">
<div class="menu-icon">
<img v-if="activeIndex === index" src="@/assets/images/equipment/选中按钮.png" alt="" />
<img
:src="activeIndex === index ? item.activeIcon : item.inactiveIcon"
:alt="item.title"
/>
</div>
</div>
</div>
</div>
<div
style="cursor: pointer"
:class="isCollapsed ? 'equipment-arrow-left' : 'equipment-arrow-right'"
@click="isCollapsed = !isCollapsed"
>
<img :src="isCollapsed ? arrowright : arrowleft" alt="" />
</div>
</template>
<script lang="ts" setup>
import { ref, withDefaults, defineProps, defineEmits } from 'vue'
import arrowleft from '@/assets/images/equipment/按钮-收缩.png'
import arrowright from '@/assets/images/equipment/按钮-展开.png'
// 定义菜单项接口
export interface MenuItem {
activeIcon: string // 高亮状态图标路径
inactiveIcon: string // 非高亮状态图标路径
title: string // 菜单项标题
}
// 定义组件属性
interface Props {
menuItems: MenuItem[] // 菜单项数组
defaultActive?: number // 默认选中项索引
collapseIcon?: string // 折叠图标
expandIcon?: string // 展开图标
}
// 设置默认属性
const props = withDefaults(defineProps<Props>(), {
defaultActive: 0
})
// 定义事件
const emit = defineEmits<{
(e: 'item-selected', index: number): void
(e: 'toggle', collapsed: boolean): void
}>()
const isCollapsed = ref(false)
// 当前选中项索引
const activeIndex = ref(props.defaultActive)
// 是否折叠
const collapsed = ref(false)
// 选择菜单项
const selectItem = (index: number) => {
activeIndex.value = index
emit('item-selected', index)
}
// 切换折叠状态
const toggleCollapse = () => {
collapsed.value = !collapsed.value
}
</script>
<style lang="less">
.equipment-item {
position: absolute;
top: 0;
left: 0;
}
.equipment-arrow-left {
position: absolute;
top: 490px;
left: -41px;
width: 150px;
img {
width: 100%;
height: 100%;
object-fit: contain;
}
}
.equipment-arrow-right {
position: absolute;
top: 490px;
left: 268px;
width: 150px;
img {
width: 100%;
height: 100%;
object-fit: contain;
}
}
.menu-icon {
display: flex;
// justify-content: space-between;
}
</style>