Ver Fonte

表头筛选、排序样式修改

zhongxiaoyu há 2 anos atrás
pai
commit
eeb3292a7c

+ 105 - 108
src/components/TableHeaderCell/index.vue

@@ -9,76 +9,84 @@
       },
     ]"
   >
-    <template v-if="!filterable || filterStyle === 'arrow'">
+    <template v-if="filterable && filterStyle === 'underline'">
+      <span
+        ref="buttonRef"
+        v-click-outside="clickOutsideHandler"
+        :class="['filter-button', { 'filter-button-active': active }]"
+      >
+        <span class="filter-button-text">{{ label }}</span>
+      </span>
+    </template>
+    <template v-else>
       <span style="flex: 1">{{ label }}</span>
     </template>
-    <template v-if="filterable">
-      <el-popover
-        :width="224"
-        trigger="click"
-        class="table-header-cell-popover"
-        placement="bottom"
-        @show="expand = true"
-        @hide="expand = false"
-      >
-        <template v-if="filterStyle === 'underline'" #reference>
-          <span
-            :class="['filter-button', { 'filter-button-active': active }]"
-            >{{ label }}</span
-          >
-        </template>
-        <template v-if="filterStyle === 'arrow'" #reference>
-          <div class="filter-arrow-wrapper">
-            <el-icon
-              :class="[
-                'filter-arrow',
-                { 'arrow-active': active, 'arrow-expand': expand },
-              ]"
-            >
-              <CaretBottom />
-            </el-icon>
-          </div>
-        </template>
-        <el-select
-          v-model="selections"
-          size="default"
-          placeholder="筛选"
-          multiple
-          filterable
-          default-first-option
-          collapse-tags
-          clearable
-          :teleported="false"
-          @change="
-            newVal => {
-              $emit('update:filter-values', newVal)
-            }
-          "
+    <div
+      v-if="(filterable && filterStyle === 'arrow') || sortable"
+      class="button-wrapper"
+    >
+      <template v-if="filterable && filterStyle === 'arrow'">
+        <el-icon
+          ref="buttonRef"
+          v-click-outside="clickOutsideHandler"
+          :class="[
+            'filter-arrow',
+            { 'arrow-active': active, 'arrow-expand': expand },
+          ]"
         >
-          <el-option
-            v-for="(option, index) in filterOptions"
-            :key="option.value + index"
-            :value="option.value"
-            :label="option.label"
-          />
-        </el-select>
-      </el-popover>
-    </template>
-    <template v-if="sortable">
-      <span class="sort-wrapper" @click="sortChange">
-        <el-icon class="sort">
+          <CaretBottom />
+        </el-icon>
+      </template>
+      <template v-if="sortable">
+        <el-icon class="sort-button" @click="sortChange">
           <SortUp v-show="sortRule === 'ascending'" />
           <SortDown v-show="sortRule === 'descending'" />
           <Sort v-show="!sortRule" />
         </el-icon>
-      </span>
-    </template>
+      </template>
+    </div>
   </div>
+  <el-popover
+    ref="popoverRef"
+    :virtual-ref="buttonRef"
+    virtual-triggering
+    trigger="click"
+    :width="224"
+    class="table-header-cell-popover"
+    placement="bottom"
+    @show="expand = true"
+    @hide="expand = false"
+  >
+    <el-select
+      v-model="selections"
+      size="default"
+      placeholder="筛选"
+      multiple
+      filterable
+      default-first-option
+      collapse-tags
+      clearable
+      :teleported="false"
+      @change="
+        newVal => {
+          $emit('update:filter-values', newVal)
+        }
+      "
+    >
+      <el-option
+        v-for="(option, index) in filterOptions"
+        :key="option.value + index"
+        :value="option.value"
+        :label="option.label"
+      />
+    </el-select>
+  </el-popover>
 </template>
 
 <script setup lang="ts">
 import { PropType } from 'vue'
 import { CaretBottom, Sort, SortUp, SortDown } from '@element-plus/icons-vue'
+import { ClickOutside as vClickOutside } from 'element-plus'
 
 const props = defineProps({
   label: {
@@ -116,6 +124,12 @@ watchEffect(() => {
     selections.value = props.filterValues
   }
 })
+const buttonRef = ref()
+const popoverRef = ref()
+const clickOutsideHandler = () => {
+  unref(popoverRef).popperRef?.delayHide?.()
+}
+
 const sortChange = () => {
   const sortRule =
     props.sortRule === ''
@@ -136,76 +150,59 @@ const sortChange = () => {
   align-items: center;
   text-align: center;
   line-height: 14px;
-  position: relative;
   &.table-header-cell-space-between {
     justify-content: space-between;
   }
-  .filter-arrow-wrapper {
-    width: 14px;
-    height: 100%;
-    background-color: #dfc37f;
-    position: relative;
-    cursor: pointer;
-    .filter-arrow {
-      display: inline;
-      position: absolute;
-      top: 0;
-      right: 0;
-      bottom: 0;
-      left: 0;
-      margin: auto;
-      transition: 0.3s transform;
-      &.arrow-expand {
-        transform: rotate(-180deg);
-      }
-      &.arrow-active {
-        color: #2d7cff;
-        font-weight: bold;
-      }
-    }
-  }
   .filter-button {
     flex: 1;
     cursor: pointer;
-    position: relative;
-
+    &-text {
+      position: relative;
+      &::after {
+        content: '';
+        display: block;
+        width: calc(100% + 4px);
+        position: absolute;
+        bottom: -4px;
+        left: -2px;
+        border-bottom: 1px solid #101116;
+      }
+    }
     &:hover {
       color: #2d7cff;
     }
-
-    &::after {
-      content: '';
-      display: block;
-      width: calc(100% + 4px);
-      position: absolute;
-      bottom: -4px;
-      left: -2px;
-      border-bottom: 1px solid #101116;
-    }
-
-    &.filter-button-active,
+    &-active,
     &:hover {
-      &::after {
+      .filter-button-text::after {
         border-bottom: 2px solid #2d7cff;
       }
     }
   }
-  .sort-wrapper {
+  .button-wrapper {
     width: 14px;
     height: 100%;
     background-color: #dfc37f;
-    position: relative;
-    cursor: pointer;
-    .sort {
-      display: inline;
-      position: absolute;
-      top: 0;
-      right: 0;
-      bottom: 0;
-      left: 0;
-      margin: auto;
+    display: flex;
+    flex-direction: column;
+    justify-content: space-around;
+    align-items: center;
+    .filter-arrow {
+      display: block;
+      transition: 0.3s transform;
+      cursor: pointer;
+      &.arrow-expand {
+        transform: rotate(-180deg);
+      }
+      &.arrow-active {
+        color: #2d7cff;
+        font-weight: bold;
+      }
     }
   }
+  .sort-button {
+    display: block;
+    cursor: pointer;
+  }
 }
 
 .el-select-dropdown__item.hover {

+ 1 - 4
src/views/realTime/components/StationForm/index.vue

@@ -100,7 +100,7 @@ watchEffect(() => {
 })
 
 const datePreTitle = (title: string) => {
-  return <div class="date-pre-title">{title}:</div>
+  return <div class="date-pre-title">{title}</div>
 }
 
 const flightStatusOptions = ref([
@@ -175,9 +175,6 @@ const waybillTypeOptions = ref([
           color: #303133;
         }
       }
-      .el-input__suffix {
-        display: none;
-      }
     }
   }
 }

+ 1 - 1
src/views/realTime/hooks/useTableData.ts

@@ -537,7 +537,7 @@ export default function useTableData(
       }
     })
     if (['航班号', '目的站'].includes(text)) {
-      width += 20
+      width += 10
     }
     return width
   }