123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- <template>
- <!-- 如果有子节点,渲染为子菜单 -->
- <ElSubMenu
- v-if="menuItemData.hasChildren && menuItemData.childs && menuItemData.childs.length"
- :index="menuItemData.id.toString()"
- :class="{ 'parent-active': isParentActive(menuItemData.id.toString()) }"
- >
- <template #title>
- <span :class="{ 'titleparent-active': isParentActive(menuItemData.id.toString()) }">
- {{ menuItemData.folderName }}
- </span>
- </template>
- <!-- 递归渲染子节点 -->
- <template v-for="child in menuItemData.childs" :key="child.id">
- <menu-item :menu-item-data="child" />
- </template>
- </ElSubMenu>
-
- <!-- 如果没有子节点,渲染为菜单项 -->
- <ElMenuItem
- v-else
- :index="menuItemData.id.toString()"
- >
- {{ menuItemData.folderName }}
- </ElMenuItem>
- </template>
- <script setup>
- import { ref, watch } from 'vue'
- // 定义组件属性
- const props = defineProps({
- menuItemData: {
- type: Object,
- required: true,
- default: () => ({
- id: '',
- parentId: '',
- projectId: '',
- contractId: '',
- folderName: '',
- hasChildren: false,
- childs: [],
- }),
- },
- selectedKeyPath: {
- type: Array,
- required: false,
- default: () => [],
- },
- })
- const selectedKeyPath = ref(props.selectedKeyPath || []) // 传入的选中路径
- watch(() => props.selectedKeyPath, (newVal) => {
- selectedKeyPath.value = newVal || []
- }, { immediate: true })
- // 菜单折叠状态
- // 判断父菜单是否应该激活
- const isParentActive = (parentIndex) => {
- return selectedKeyPath.value.includes(parentIndex)
- }
- </script>
- <style scoped>
- /* 基础菜单样式 */
- /* 菜单项基础样式 */
- .custom-menu .el-menu-item,
- .custom-menu .el-sub-menu__title {
- position: relative;
- transition: all 0.3s ease;
- }
- /* 选中菜单项样式 */
- .custom-menu .el-menu-item.is-active {
- color: #149BF4 !important;
- background-color: #E6F7FF !important;
- }
- /* 选中菜单项右侧边框 */
- .custom-menu .el-menu-item.is-active::after {
- content: '';
- position: absolute;
- right: 0;
- top: 0;
- height: 100%;
- width: 6px;
- background-color: #149BF4;
- }
- /* 父菜单标题激活样式 */
- .titleparent-active {
- color: #149BF4 !important;
- font-weight: bold !important;
- }
- /* 父菜单激活时箭头变色 - 通过父级激活类控制 */
- .parent-active .el-sub-menu__icon-arrow {
- color: #149BF4 !important;
- }
- /* 解决scoped样式穿透问题 */
- /* :deep(.parent-active) .el-sub-menu__icon-arrow {
- color: #149BF4 !important;
- } */
- :deep(.el-sub-menu.parent-active) .el-sub-menu__icon-arrow {
- color: #149BF4 !important;
- transition: color 0.3s ease;
- }
- /* 方
- /* 二级菜单背景色 - 保持f7f7f7 */
- .custom-menu .el-sub-menu .el-menu {
- background-color: #F7F7F7 !important;
- }
- /* 二级菜单项默认样式 */
- .custom-menu .el-sub-menu .el-menu .el-menu-item {
- background-color: #F7F7F7 !important;
- }
- /* 二级菜单项选中样式 */
- .custom-menu .el-sub-menu .el-menu .el-menu-item.is-active {
- background-color: #E6F7FF !important;
- }
- </style>
|