header.vue 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. <template>
  2. <div class="trademark mr-8 flex items-center text-white">
  3. <img :src="loginLogin" class="w-10 h-10 mr-4" />
  4. <div class="text-nowrap">客户管家</div>
  5. </div>
  6. <div class=" flex flex-row justify-start items-center text-white flex-1 parentDiv" ref="parentDiv">
  7. <div v-for="(routerItem, routerItemIdex) in routerList"
  8. :class="`border-b-2 border-transparent hover:border-white p-2 mr-4 cursor-pointer multipleyHeader ${activeRouter?.path === routerItem.path ? 'border-white' : ''}`"
  9. :key="routerItem.path" ref="childDivs" v-show="visibleItems.includes(routerItemIdex)">
  10. <div v-if="routerItem.children && routerItem.children.length <= 0" @click="setCurrentRouter(routerItem)" class="text-nowrap">
  11. {{ routerItem.name }}
  12. </div>
  13. <div v-else class="flex justify-center items-center">
  14. <el-dropdown>
  15. <div class="text-white w-full h-full headerText">
  16. {{ routerItem.name }}
  17. <el-icon class="el-icon--right">
  18. <arrow-down />
  19. </el-icon>
  20. </div>
  21. <template #dropdown>
  22. <el-dropdown-menu>
  23. <el-dropdown-item v-for="child in routerItem.children" :key="child.path" @click="setCurrentRouter(child)">
  24. {{ child.name }}
  25. </el-dropdown-item>
  26. </el-dropdown-menu>
  27. </template>
  28. </el-dropdown>
  29. </div>
  30. </div>
  31. </div>
  32. <div class="flex flex-row justify-start items-center text-white header-right">
  33. <el-icon :size="26" class="ml-4 cursor-pointer">
  34. <Bell />
  35. </el-icon>
  36. <div>
  37. <img class="w-8 h-8 rounded-full ml-4 cursor-pointer" :src="defaultCover" alt="" @click="logout()">
  38. </div>
  39. <el-icon :size="26" class="ml-4 cursor-pointer">
  40. <Grid />
  41. </el-icon>
  42. </div>
  43. </template>
  44. <script lang="ts" setup>
  45. import { onMounted, ref, watchEffect } from 'vue';
  46. import { RouteRecordRaw, useRouter } from 'vue-router';
  47. import { useStore } from "../../store/index"
  48. import defaultCover from "../../assets/defaultCover.png";
  49. import loginLogin from '../../assets/login/login_logo.png'
  50. const { routers, clearStore } = useStore()
  51. const router = useRouter();
  52. const routerList = ref<RouteRecordRaw[]>([]);
  53. const activeRouter = ref<RouteRecordRaw>();
  54. const visibleItems = ref<number[]>([]);
  55. const parentDiv = ref<HTMLElement | null>(null);
  56. const updateVisibleItems = () => {
  57. const parentWidth = parentDiv.value?.offsetWidth || 10;
  58. const canvas = document.createElement('canvas');
  59. const context = canvas.getContext('2d');
  60. let textWidthList: any = [] // 所有文字的宽度
  61. let totalWidth = 0;
  62. let temporaryIndex: any = []
  63. if(context) {
  64. context.font = '16px 微软雅黑';
  65. textWidthList = routerList.value.map((item: any) => {
  66. const metrics = context.measureText(item.name);
  67. return Math.ceil(metrics.width) + 32; // 32是padding和margin的宽度
  68. })
  69. }
  70. for(let i in textWidthList) {
  71. if(totalWidth + textWidthList[i] > parentWidth) {
  72. break;
  73. }
  74. totalWidth += textWidthList[i];
  75. temporaryIndex.push(+i);
  76. }
  77. // 替换最后一个元素
  78. let lastIndex = textWidthList.length - 1;
  79. temporaryIndex.splice(temporaryIndex.length -1, 1, lastIndex)
  80. visibleItems.value = temporaryIndex;
  81. console.log(visibleItems.value)
  82. };
  83. const setCurrentRouter = (item: RouteRecordRaw) => {
  84. activeRouter.value = item;
  85. if (item.children && item.children.length > 0) {
  86. router.push({ path: item.children[0].path });
  87. return
  88. }
  89. router.push({ path: item.path });
  90. };
  91. const logout = () => {
  92. clearStore();
  93. router.push({ path: '/login' });
  94. };
  95. onMounted(() => {
  96. routerList.value = routers;
  97. activeRouter.value = routerList.value.find((item) => item.path === router.currentRoute.value.path);
  98. console.log("routerList", routerList);
  99. window.addEventListener('resize', updateVisibleItems);
  100. setTimeout(() => {
  101. updateVisibleItems();
  102. }, 500);
  103. })
  104. watchEffect(() => {
  105. updateVisibleItems();
  106. });
  107. </script>
  108. <style scoped lang="scss">
  109. .trademark {
  110. font-size: 20px;
  111. }
  112. .multipleyHeader {
  113. height: 96%;
  114. display: flex;
  115. align-items: center;
  116. text-wrap: nowrap;
  117. .headerText {
  118. font-size: 16px;
  119. }
  120. }
  121. .parentBox {
  122. // max-width: 80%;
  123. // min-width: 300px;
  124. flex: 1;
  125. overflow: hidden;
  126. }
  127. .header-right {
  128. width: 135px;
  129. }
  130. .parentDiv {
  131. width: 50%;
  132. }
  133. </style>