index.vue 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. <!-- 分栏布局 -->
  2. <template>
  3. <el-container class="layout">
  4. <div class="aside-split">
  5. <div class="logo flx-center">
  6. <img class="logo-img" src="@/assets/images/eco-1.png" alt="logo" />
  7. </div>
  8. <el-scrollbar>
  9. <div class="split-list">
  10. <div
  11. v-for="item in menuList"
  12. :key="item.path"
  13. class="split-item"
  14. :class="{ 'split-active': splitActive === item.path || `/${splitActive.split('/')[1]}` === item.path }"
  15. @click="changeSubMenu(item)"
  16. >
  17. <svg-icon v-if="item.meta.icon" :name="item.meta.icon" />
  18. <span class="title">{{ item.meta.title }}</span>
  19. </div>
  20. </div>
  21. </el-scrollbar>
  22. </div>
  23. <el-aside :class="{ 'not-aside': !subMenuList.length }" :style="{ width: isCollapse ? '65px' : '210px' }">
  24. <div class="logo flx-center">
  25. <span v-show="subMenuList.length" class="logo-text">{{ isCollapse ? 'C' : title }}</span>
  26. </div>
  27. <el-scrollbar>
  28. <el-menu :router="false" :default-active="activeMenu" :collapse="isCollapse" :unique-opened="accordion" :collapse-transition="false">
  29. <SubMenu :menu-list="subMenuList" />
  30. </el-menu>
  31. </el-scrollbar>
  32. </el-aside>
  33. <el-container>
  34. <el-header>
  35. <ToolBarLeft />
  36. <ToolBarRight />
  37. </el-header>
  38. <Main />
  39. </el-container>
  40. </el-container>
  41. </template>
  42. <script setup lang="ts" name="layoutColumns">
  43. import { useAuthStore } from '@/stores/modules/auth'
  44. import { useGlobalStore } from '@/stores/modules/global'
  45. import Main from '@/layouts/components/Main/index.vue'
  46. import ToolBarLeft from '@/layouts/components/Header/ToolBarLeft.vue'
  47. import ToolBarRight from '@/layouts/components/Header/ToolBarRight.vue'
  48. import SubMenu from '@/layouts/components/Menu/SubMenu.vue'
  49. const title = import.meta.env.VITE_GLOB_APP_TITLE
  50. const route = useRoute()
  51. const router = useRouter()
  52. const authStore = useAuthStore()
  53. const globalStore = useGlobalStore()
  54. const accordion = computed(() => globalStore.accordion)
  55. const isCollapse = computed(() => globalStore.isCollapse)
  56. const menuList = computed(() => authStore.showMenuListGet)
  57. const activeMenu = computed(() => (route.meta.activeMenu ? route.meta.activeMenu : route.path) as string)
  58. const subMenuList = ref<Menu.MenuOptions[]>([])
  59. const splitActive = ref('')
  60. watch(
  61. () => [menuList, route],
  62. () => {
  63. // 当前菜单没有数据直接 return
  64. if (!menuList.value.length) return
  65. splitActive.value = route.path
  66. const menuItem = menuList.value.filter((item: Menu.MenuOptions) => {
  67. return route.path === item.path || `/${route.path.split('/')[1]}` === item.path
  68. })
  69. if (menuItem[0].children?.length) return (subMenuList.value = menuItem[0].children)
  70. subMenuList.value = []
  71. },
  72. {
  73. deep: true,
  74. immediate: true
  75. }
  76. )
  77. // change SubMenu
  78. const changeSubMenu = (item: Menu.MenuOptions) => {
  79. splitActive.value = item.path
  80. if (item.children?.length) return (subMenuList.value = item.children)
  81. subMenuList.value = []
  82. router.push(item.path)
  83. }
  84. </script>
  85. <style scoped lang="scss">
  86. @import './index';
  87. </style>