el-select单选,根据选项内容自适应Select选择器宽度

348 阅读1分钟

方案一:使用隐藏元素来动态计算选项文本的宽度

<template>
  <div>
    <el-select v-model="selected" :style="{ width: selectWidth + 'px' }">
      <el-option
        v-for="item in options"
        :key="item.value"
        :label="item.label"
        :value="item.value"
      ></el-option>
    </el-select>

    <!-- 隐藏元素计算文本宽度 -->
    <span ref="textWidthCalculator" class="hidden">{{ selectedLabel }}</span>
  </div>
</template>

<script setup>
import { ref, watch, computed, nextTick } from "vue";

const options = [
  { value: "option1", label: "juejin" },
  { value: "option2", label: "Denver Nuggets" },
  // ... 
];

const selected = ref(options[0].value);
const textWidthCalculator = ref(null);

const selectedLabel = computed(() => {
  const option = options.find((option) => option.value === selected.value);
  return option ? option.label : "";
});

watch(selected, async () => {
  await nextTick();
  const width = textWidthCalculator.value.offsetWidth;
  selectWidth.value = width + 30; // 加上一些额外的padding值或其他偏移量
});

const selectWidth = ref(100); // 默认宽度
</script>

<style scoped>
.hidden {
  display: inline-block;
  visibility: hidden;
  white-space: nowrap;
  font-size: 14px; //字体大小与el-select使用的字体大小一致,否则计算出的宽度不准确
}
</style>

方案二:使用HTML5 canvas来估算文本的宽度,要求浏览器支持canvas。

<template>
  <div>
    <el-select v-model="selected" :style="{ width: selectWidth + 'px' }">
      <el-option
        v-for="item in options"
        :key="item.value"
        :label="item.label"
        :value="item.value"
      ></el-option>
    </el-select>
  </div>
</template>

<script setup>
import { ref, watch, computed } from "vue";

const options = [
  { value: "option1", label: "juejin" },
  { value: "option2", label: "Denver Nuggets" },
  // ... 
];

const selected = ref(options[0].value);

//此计算属性返回当前选定选项的标签
const selectedLabel = computed(() => {
  const option = options.find((option) => option.value === selected.value);
  return option ? option.label : "";
});

//通过canvas的measureText方法测量文本宽度
const measureTextWidth = (text) => {
  const canvas = document.createElement("canvas");
  const ctx = canvas.getContext("2d");
  ctx.font = "14px Arial"; // 字体样式要与el-select的样式匹配,否则计算出的宽度不准确
  return ctx.measureText(text).width;
};

const selectWidth = ref(100); // 默认宽度

watch(selectedLabel, (newLabel) => {
  const width = measureTextWidth(newLabel);
  selectWidth.value = width + 30; // 加上一些额外的padding值或其他偏移量
});
</script>