소스 검색

统一处理下拉框宽度

gongtianxiao 1 개월 전
부모
커밋
15ab854a19

+ 93 - 47
src/components/base/BaseSelect.vue

@@ -1,49 +1,78 @@
 <template>
   <div class="filter-group">
-    <label class="filter-label">{{ text }}</label>
-    <div class="filter-select" @click="handleSelect">
-      <span class="filter-select-text">{{ selectedText }}</span>
-      <span class="filter-select-arrow"><img src="@/assets/images/Vector.png"></span>
-    </div>
+    <label v-if="text" class="filter-label">{{ text }}</label>
+    <div class="filter-select-wrap" :style="selectWrapStyle">
+      <div class="filter-select" @click="handleSelect">
+        <span class="filter-select-text" :title="displayText">{{ displayText }}</span>
+        <span class="filter-select-arrow"><img src="@/assets/images/Vector.png" alt=""></span>
+      </div>
 
-    <div
-      class="filter-select-options"
-      v-if="showOptions"
-      :style="optionsPanelStyle"
-      @mouseleave="handleOptionMouseLeave"
-    >
-      <div class="filter-select-option" v-for="option in options" :key="option.value" @click="handleOptionClick(option)">
-        <span class="filter-select-option-text">{{ option.text }}</span>
+      <div
+        class="filter-select-options"
+        v-if="showOptions"
+        :style="optionsPanelStyle"
+        @mouseleave="handleOptionMouseLeave"
+      >
+        <div
+          class="filter-select-option"
+          v-for="option in options"
+          :key="option.value"
+          :title="option.text"
+          @click="handleOptionClick(option)"
+        >
+          <span class="filter-select-option-text">{{ option.text }}</span>
+        </div>
       </div>
     </div>
   </div>
 </template>
 
 <script setup>
-import { defineProps, ref, defineEmits, watch, computed } from 'vue'
-const emit = defineEmits(['selected'])
-const showOptions = ref(false)
+import { defineProps, ref, defineEmits, watch, computed } from 'vue';
+
+const emit = defineEmits(['selected']);
+const showOptions = ref(false);
 
 const props = defineProps({
   text: {
     type: String,
+    default: '',
   },
   selectedText: {
     type: String,
+    default: '',
   },
   options: {
     type: Array,
     default: () => [],
   },
+  /** 下拉框固定宽度,数字为 px */
+  selectWidth: {
+    type: [Number, String],
+    default: 128,
+  },
   /** 下拉选项区最大高度,超出滚动 */
   maxOptionsHeight: {
     type: [Number, String],
     default: 0,
   },
-})
+});
 
-const selectedText = ref(props.selectedText)
-const options = ref(props.options)
+const selectedText = ref(props.selectedText);
+const options = ref(props.options);
+
+const resolveWidth = (val) => (typeof val === 'number' ? `${val}px` : val);
+
+const selectWrapStyle = computed(() => {
+  const width = resolveWidth(props.selectWidth);
+  return {
+    width,
+    minWidth: width,
+    maxWidth: width,
+  };
+});
+
+const displayText = computed(() => props.selectedText || selectedText.value || '');
 
 const optionsPanelStyle = computed(() => {
   if (!props.maxOptionsHeight) return undefined;
@@ -51,21 +80,21 @@ const optionsPanelStyle = computed(() => {
     ? `${props.maxOptionsHeight}px`
     : props.maxOptionsHeight;
   return { maxHeight: height };
-})
+});
 
 const handleSelect = () => {
-  showOptions.value = !showOptions.value
-}
+  showOptions.value = !showOptions.value;
+};
 
 const handleOptionMouseLeave = () => {
-  showOptions.value = false
-}
+  showOptions.value = false;
+};
 
 const handleOptionClick = (option) => {
-  selectedText.value = option.text
-  showOptions.value = false
-  emit('selected', option.value)
-}
+  selectedText.value = option.text;
+  showOptions.value = false;
+  emit('selected', option.value);
+};
 
 watch(() => props.selectedText, (newVal) => {
   selectedText.value = newVal;
@@ -79,14 +108,14 @@ watch(() => props.options, (newVal) => {
 <style scoped>
 .filter-group {
   height: 36px;
-  position: relative; 
+  position: relative;
   display: flex;
   align-items: center;
-  gap: 8.01px;
+  gap: 8px;
+  flex-shrink: 0;
 }
 
 .filter-label {
-  /* width: 59px; */
   height: 16px;
   font-family: var(--font-regular);
   font-weight: 400;
@@ -96,58 +125,70 @@ watch(() => props.options, (newVal) => {
   vertical-align: middle;
   color: var(--color-text-primary);
   white-space: nowrap;
+  flex-shrink: 0;
+}
+
+.filter-select-wrap {
+  position: relative;
+  flex-shrink: 0;
 }
 
 .filter-select {
+  width: 100%;
   height: 36px;
   border-radius: var(--radius-sm);
-  border-width: 1px;
   padding: 8px 12px;
   gap: 8px;
   background: var(--color-surface);
   border: 1px solid var(--color-input-border);
   display: flex;
   align-items: center;
-  justify-content: center;
+  justify-content: space-between;
+  box-sizing: border-box;
   cursor: pointer;
 }
 
-.filter-select-text{
+.filter-select-text {
+  flex: 1;
+  min-width: 0;
   height: 16px;
   font-family: var(--font-regular);
   font-weight: 400;
   font-size: 14px;
   line-height: 16px;
-  letter-spacing: 0px;
-  vertical-align: middle;
+  letter-spacing: 0;
   color: var(--color-text-body);
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
 }
 
-.filter-select-arrow{
+.filter-select-arrow {
   width: 18px;
   height: 18px;
   display: flex;
   align-items: center;
-  justify-content: center; 
+  justify-content: center;
+  flex-shrink: 0;
 }
 
-.filter-select-options{
+.filter-select-options {
   position: absolute;
   top: calc(100% + 4px);
   left: 0;
-  min-width: 100%;
-  width: max-content;
-  max-width: 280px;
+  width: 100%;
+  box-sizing: border-box;
   background: var(--color-surface);
   border: 1px solid var(--color-input-border);
   border-radius: var(--radius-sm);
   padding: 4px 0;
   z-index: 1000;
   overflow-y: auto;
+  overflow-x: hidden;
   box-shadow: var(--shadow-dropdown);
 }
 
-.filter-select-option{
+.filter-select-option {
   min-height: 36px;
   border-radius: 0;
   padding: 8px 12px;
@@ -156,6 +197,7 @@ watch(() => props.options, (newVal) => {
   display: flex;
   align-items: center;
   cursor: pointer;
+  min-width: 0;
 }
 
 .filter-select-option:last-child {
@@ -166,14 +208,18 @@ watch(() => props.options, (newVal) => {
   background: var(--color-accent-hover);
 }
 
-.filter-select-option-text{
+.filter-select-option-text {
+  width: 100%;
+  min-width: 0;
   height: 16px;
   font-family: var(--font-regular);
   font-weight: 400;
   font-size: 14px;
   line-height: 16px;
-  letter-spacing: 0px;
-  vertical-align: middle;
+  letter-spacing: 0;
   color: var(--color-text-body);
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
 }
-</style>
+</style>

+ 1 - 5
src/components/layout/PageHeader.vue

@@ -8,6 +8,7 @@
           text="当前集团"
           :selected-text="filterStore.selectManageGroup"
           :options="manageGroupOptions"
+          :select-width="128"
           :max-options-height="320"
           @selected="filterStore.setManageGroup"
         />
@@ -144,7 +145,6 @@ onMounted(() => {
 }
 
 .manage-context__group :deep(.filter-select) {
-  min-width: 120px;
   background: var(--color-accent-soft);
   border-color: var(--color-accent-border-strong);
 }
@@ -206,9 +206,5 @@ onMounted(() => {
   .manage-context {
     gap: 10px;
   }
-
-  .manage-context__group :deep(.filter-select) {
-    min-width: 100px;
-  }
 }
 </style>

+ 7 - 0
src/components/manage/asset/BatchEditModal.vue

@@ -10,6 +10,7 @@
             <BaseSelect
               :selected-text="selectedFieldLabel"
               :options="fieldSelectOptions"
+              select-width="100%"
               :max-options-height="280"
               @selected="selectedFieldKey = $event"
             />
@@ -183,6 +184,12 @@ const handleSubmit = () => {
   display: none;
 }
 
+.batch-edit-form__field--select :deep(.filter-select-wrap) {
+  width: 100%;
+  min-width: 0;
+  max-width: none;
+}
+
 .batch-edit-form__field--select :deep(.filter-select) {
   width: 100%;
   justify-content: space-between;

+ 1 - 0
src/components/manage/asset/FullAssetListPanel.vue

@@ -36,6 +36,7 @@
           text="房屋用途"
           :selectedText="filterUsage"
           :options="fwUsageOptions"
+          :select-width="168"
           :max-options-height="240"
           @selected="filterUsage = $event"
         />

+ 2 - 0
src/components/stats/FullDataList.vue

@@ -24,6 +24,7 @@
           text="房屋用途"
           :selected-text="fwUsageLabel"
           :options="fwUsageOptions"
+          :select-width="168"
           :max-options-height="240"
           @selected="patchFilters({ fwUsage: $event })"
         />
@@ -49,6 +50,7 @@
           text="土地类型"
           :selected-text="landTypeLabel"
           :options="landTypeOptions"
+          :select-width="168"
           :max-options-height="240"
           @selected="patchFilters({ landUsage: $event })"
         />

+ 3 - 0
src/pages/Topic3Page.vue

@@ -142,6 +142,7 @@
               text="房屋用途"
               :selected-text="filterPurpose"
               :options="purposeOptions"
+              :select-width="168"
               :max-options-height="240"
               @selected="filterPurpose = $event"
             />
@@ -149,12 +150,14 @@
               text="闲置时长"
               :selected-text="filterIdleMonthsLabel"
               :options="IDLE_MONTHS_OPTIONS"
+              :select-width="148"
               @selected="onIdleMonthsSelect"
             />
             <BaseSelect
               text="闲置率区间"
               :selected-text="filterIdleBucketLabel"
               :options="IDLE_RATE_OPTIONS"
+              :select-width="148"
               @selected="onIdleBucketSelect"
             />
             <BaseSelect