cwg-submenu.vue 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. <template>
  2. <view class="cwg-submenu">
  3. <view class="submenu">
  4. <view class="cwg-submenu-item" :class="{ 'active': activePath === item.path }" v-for="item in submenuItems"
  5. :key="item.path" @click="handleClick(item)">
  6. <text v-t="item.label"></text>
  7. <cwg-icon v-if="item.isExternal" name="crm-fx" :size="20" :color="!isDark ? '#6c8595' : '#fff'" />
  8. </view>
  9. </view>
  10. </view>
  11. </template>
  12. <script lang="ts" setup>
  13. import { computed, watch, nextTick } from 'vue';
  14. import { openExternalUrl } from '@/utils/openExternalUrl'
  15. import { useI18n } from 'vue-i18n'
  16. import { lang } from '@/composables/config'
  17. import { switchAppLanguage } from '@/locale/index'
  18. const { locale } = useI18n()
  19. import useRouter from "@/hooks/useRouter";
  20. const router = useRouter();
  21. import useRoute from '@/hooks/useRoute'
  22. const route = useRoute()
  23. import useGlobalStore from '@/stores/use-global-store'
  24. const globalStore = useGlobalStore()
  25. const isDark = computed(() => globalStore.theme === 'dark')
  26. interface MenuItem {
  27. key: string;
  28. label: string;
  29. icon?: string;
  30. type?: string;
  31. lang?: string;
  32. path?: string;
  33. isExternal?: boolean;
  34. children?: MenuItem[];
  35. }
  36. const props = defineProps({
  37. submenuItems: {
  38. type: Array as () => MenuItem[],
  39. default: () => []
  40. }
  41. })
  42. const activePath = computed(() => route.path + (route.query?.type ? `?type=${route.query.type}` : '') || '')
  43. const emit = defineEmits(['submenu-click']);
  44. function handleClick(item: MenuItem) {
  45. if (item.type == 'lang') {
  46. handleMenuClick(item.lang)
  47. } else {
  48. if (item.isExternal) {
  49. openExternalUrl(item.path);
  50. } else if (route.path !== item.path) {
  51. router.push(item.path);
  52. }
  53. }
  54. emit('submenu-click', item)
  55. }
  56. function handleMenuClick(a: string) {
  57. switchAppLanguage(a, { locale, lang })
  58. }
  59. </script>
  60. <style scoped lang="scss">
  61. @import "@/uni.scss";
  62. .cwg-submenu {
  63. width: 100%;
  64. .submenu {
  65. width: 100%;
  66. display: flex;
  67. flex-direction: column;
  68. align-items: center;
  69. gap: px2rpx(8);
  70. padding: px2rpx(8) px2rpx(8) px2rpx(8) px2rpx(32);
  71. box-sizing: border-box;
  72. }
  73. .cwg-submenu-item {
  74. width: 100%;
  75. height: px2rpx(40);
  76. cursor: pointer;
  77. display: flex;
  78. align-items: center;
  79. justify-content: space-between;
  80. gap: 12px;
  81. padding: px2rpx(10);
  82. box-sizing: border-box;
  83. font-size: 14px;
  84. .tabler-icon-external-link {
  85. width: px2rpx(20);
  86. height: px2rpx(20);
  87. }
  88. &:hover {
  89. background: rgba(108, 133, 149, 0.12) !important;
  90. border: 1px solid rgb(145, 163, 176) !important;
  91. border-radius: px2rpx(4);
  92. }
  93. &.active {
  94. background: rgba(108, 133, 149, 0.12) !important;
  95. border-radius: px2rpx(4);
  96. }
  97. }
  98. }
  99. </style>