index.vue 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. <script setup lang="ts">
  2. import { useI18n } from "vue-i18n";
  3. import { ref, computed } from "vue";
  4. import { noticesData } from "./data";
  5. import NoticeList from "./components/NoticeList.vue";
  6. import BellIcon from "~icons/ep/bell";
  7. const { t } = useI18n();
  8. const noticesNum = ref(0);
  9. const notices = ref(noticesData);
  10. const activeKey = ref(noticesData[0]?.key);
  11. notices.value.map(v => (noticesNum.value += v.list.length));
  12. const getLabel = computed(
  13. () => item =>
  14. t(item.name) + (item.list.length > 0 ? `(${item.list.length})` : "")
  15. );
  16. </script>
  17. <template>
  18. <el-dropdown trigger="click" placement="bottom-end">
  19. <span
  20. :class="[
  21. 'dropdown-badge',
  22. 'navbar-bg-hover',
  23. 'select-none',
  24. Number(noticesNum) !== 0 && 'mr-[10px]'
  25. ]"
  26. >
  27. <el-badge :value="Number(noticesNum) === 0 ? '' : noticesNum" :max="99">
  28. <span class="header-notice-icon">
  29. <IconifyIconOffline :icon="BellIcon" />
  30. </span>
  31. </el-badge>
  32. </span>
  33. <template #dropdown>
  34. <el-dropdown-menu>
  35. <el-tabs
  36. v-model="activeKey"
  37. :stretch="true"
  38. class="dropdown-tabs"
  39. :style="{ width: notices.length === 0 ? '200px' : '330px' }"
  40. >
  41. <el-empty
  42. v-if="notices.length === 0"
  43. :description="t('status.pureNoMessage')"
  44. :image-size="60"
  45. />
  46. <span v-else>
  47. <template v-for="item in notices" :key="item.key">
  48. <el-tab-pane :label="getLabel(item)" :name="`${item.key}`">
  49. <el-scrollbar max-height="330px">
  50. <div class="noticeList-container">
  51. <NoticeList :list="item.list" :emptyText="item.emptyText" />
  52. </div>
  53. </el-scrollbar>
  54. </el-tab-pane>
  55. </template>
  56. </span>
  57. </el-tabs>
  58. </el-dropdown-menu>
  59. </template>
  60. </el-dropdown>
  61. </template>
  62. <style lang="scss" scoped>
  63. .dropdown-badge {
  64. display: flex;
  65. align-items: center;
  66. justify-content: center;
  67. width: 40px;
  68. height: 48px;
  69. cursor: pointer;
  70. .header-notice-icon {
  71. font-size: 18px;
  72. }
  73. }
  74. .dropdown-tabs {
  75. .noticeList-container {
  76. padding: 15px 24px 0;
  77. }
  78. :deep(.el-tabs__header) {
  79. margin: 0;
  80. }
  81. :deep(.el-tabs__nav-wrap)::after {
  82. height: 1px;
  83. }
  84. :deep(.el-tabs__nav-wrap) {
  85. padding: 0 36px;
  86. }
  87. }
  88. </style>