index.vue 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. <template>
  2. <div class="hc-sb-table">
  3. <svg class="svg-tabs" height="45px" width="40px" xmlns="http://www.w3.org/2000/svg"
  4. xmlns:xlink="http://www.w3.org/1999/xlink">
  5. <clipPath id="tabs">
  6. <path d="M40,45C15,36,33,0,0,0v45H40z" fill-rule="evenodd"/>
  7. </clipPath>
  8. </svg>
  9. <el-tabs v-model="curKey" :class="curIndex === 0 ? 'first' : curIndex === datas.length-1 ? 'fourth' : ''"
  10. @tab-change="tabClick">
  11. <el-tab-pane v-for="item in datas" :label="item.label" :name="item.key">
  12. <template #label>
  13. <HcIcon v-if="item.icon" :name="item.icon" class="icon"/>
  14. <span class="name">{{ item.label }}</span>
  15. </template>
  16. <slot :name='`tab-${item.key}`'/>
  17. </el-tab-pane>
  18. </el-tabs>
  19. </div>
  20. </template>
  21. <script setup>
  22. import {nextTick, ref, watch} from "vue";
  23. import {arrIndex} from "js-fast-way"
  24. const props = defineProps({
  25. datas: {
  26. type: Array,
  27. default: () => []
  28. },
  29. cur: {
  30. type: [String, Number],
  31. default: ''
  32. }
  33. })
  34. //初始变量
  35. const curKey = ref(props.cur)
  36. const curIndex = ref(0)
  37. //监听
  38. watch(() => [
  39. props.cur,
  40. props.datas
  41. ], ([cur, datas]) => {
  42. curKey.value = cur
  43. getCurIndex(datas, cur)
  44. })
  45. //挂载完成
  46. nextTick(() => {
  47. getCurIndex(props.datas, props.cur)
  48. })
  49. //获取索引
  50. const getCurIndex = (datas, key) => {
  51. curIndex.value = arrIndex(datas, 'key', key)
  52. }
  53. //事件
  54. const emit = defineEmits(['tabClick'])
  55. const tabClick = (key) => {
  56. curKey.value = key;
  57. getCurIndex(props.datas, key)
  58. emit('tabClick', key)
  59. }
  60. </script>
  61. <style lang="scss" scoped>
  62. .hc-sb-table {
  63. position: relative;
  64. height: 100%;
  65. .svg-tabs {
  66. opacity: 0;
  67. width: 0;
  68. height: 0;
  69. }
  70. }
  71. </style>
  72. <style lang="scss">
  73. .hc-sb-table .el-tabs {
  74. position: relative;
  75. margin-top: -18px;
  76. height: 100%;
  77. filter: drop-shadow(0 0 10px rgba(0, 0, 0, 0.1));
  78. .el-tabs__header {
  79. margin-bottom: 0;
  80. .el-tabs__nav-wrap::after {
  81. background-color: transparent;
  82. }
  83. .el-tabs__nav {
  84. height: 45px;
  85. .el-tabs__item {
  86. margin-top: 5px;
  87. padding: 0 20px;
  88. user-select: none;
  89. display: inline-flex;
  90. align-content: center;
  91. --el-text-color-primary: #838791;
  92. background-color: #E5EBEF;
  93. &::after {
  94. content: '';
  95. position: absolute;
  96. width: 1px;
  97. height: 15px;
  98. background-color: #CCCCCC;
  99. top: 12px;
  100. left: 0;
  101. }
  102. .hc-icon-i {
  103. margin-right: 5px;
  104. }
  105. .hc-icon-i, .name {
  106. position: relative;
  107. z-index: 10;
  108. }
  109. }
  110. .el-tabs__item:nth-child(2) {
  111. border-radius: 10px 0 0 0;
  112. &::after {
  113. display: none;
  114. }
  115. }
  116. .el-tabs__item:last-child {
  117. border-radius: 0 10px 0 0;
  118. }
  119. }
  120. }
  121. .el-tabs__active-bar {
  122. position: absolute;
  123. height: 45px;
  124. background: #f1f5f8;
  125. &::after,
  126. &::before {
  127. content: '';
  128. background: #f1f5f8;
  129. width: 40px;
  130. position: absolute;
  131. height: 45px;
  132. top: 0px;
  133. clip-path: url(#tabs);
  134. right: -40px;
  135. }
  136. &::before {
  137. left: -40px;
  138. right: auto;
  139. // 水平翻转
  140. transform: scaleX(-1);
  141. }
  142. }
  143. &.first .el-tabs__active-bar {
  144. &::before {
  145. transform: scaleX(1);
  146. left: -20px;
  147. clip-path: none;
  148. border-radius: 15px 0 0 0;
  149. }
  150. }
  151. &.fourth .el-tabs__active-bar {
  152. &::after {
  153. transform: scaleX(-1);
  154. right: -20px;
  155. clip-path: none;
  156. border-radius: 15px 0 0 0;
  157. }
  158. }
  159. .el-tabs__content {
  160. padding: 0;
  161. background: #f1f5f8;
  162. border-radius: 0 10px 10px 10px;
  163. height: calc(100vh - 140px);
  164. .el-tab-pane {
  165. position: relative;
  166. height: 100%;
  167. .hc-card-box.el-card {
  168. height: 100%;
  169. box-shadow: none;
  170. border-radius: initial;
  171. }
  172. }
  173. }
  174. }
  175. </style>