首页Vue根据传入的文本宽度计算平均宽度并返回(用于el-table中的设置宽度)

根据传入的文本宽度计算平均宽度并返回(用于el-table中的设置宽度)

分类Vue时间2025-05-27 12:52:58发布RustStream浏览104
摘要:/** * 根据传入的文本计算宽度 * @description 计算文本宽度,可选择平均宽度或最大宽度模式,保留两位小数 * @param texts 文本数组 例如 ['文本1', '文本2', '文本3'] * @param font 文本信息 例如 '14px sans-serif' * @param extraSpace 额外空间,默认值为100px * @param minWidth 最小宽度,默认值为100px * @param useMaxWidth 是否使用最大宽度模式,默认false使用平均宽度 * @returns 返回计算后的宽度,单位为px */ calculateTextWidth(texts, {font = '14px sans-serif', extraSpace = 50, minWidth = 100, useMaxWidth = false} = {} { // 创建离屏canvas用于测量文本宽度 const canvas = document.createElement('canvas' ; const context = canvas.getContext('2d' ; // 设置字体 context.font = font; // 计算每个文本的宽度 const widths = texts.map(text =<!--autointro-->...
/**
     * 根据传入的文本计算宽度
     * @description 计算文本宽度,可选择平均宽度或最大宽度模式,保留两位小数
     * @param texts 文本数组  例如 ['文本1', '文本2', '文本3']
     * @param font 文本信息 例如 '14px sans-serif'
     * @param extraSpace 额外空间,默认值为100px
     * @param minWidth 最小宽度,默认值为100px
     * @param useMaxWidth 是否使用最大宽度模式,默认false使用平均宽度
     * @returns 返回计算后的宽度,单位为px
     */
    calculateTextWidth(texts, {font = '14px sans-serif', extraSpace = 50, minWidth = 100, useMaxWidth = false} = {}) {        
      // 创建离屏canvas用于测量文本宽度
      const canvas = document.createElement('canvas');
      const context = canvas.getContext('2d');
      
      // 设置字体
      context.font = font;
      
      // 计算每个文本的宽度
      const widths = texts.map(text => {
        const width = context.measureText(text).width;
        return width;
      });
      
      if (useMaxWidth) {
        // 最大宽度模式:取所有宽度中的最大值加上额外空间
        const maxWidth = Math.max(...widths) + extraSpace;
        const finalWidth = Math.max(maxWidth, minWidth);
        console.log('最终宽度(最大宽度模式):', finalWidth, 'px');
        return `${finalWidth}px`;
      } else {
        // 平均宽度模式:移除一个最大值和一个最小值后取平均
        // 排序宽度数组(从小到大)
        widths.sort((a, b) => a - b);
        
        // 移除一个最大值和一个最小值
        const filteredWidths = widths.slice(1, widths.length - 1);
        
        // 计算过滤后的总宽度
        const sum = filteredWidths.reduce((total, width) => total + width, 0);
        
        // 计算平均值,至少保留两位小数
        const average = filteredWidths.length > 0 
          ? parseFloat((sum / filteredWidths.length).toFixed(2)) 
          : 0;
        
        // 添加额外空间并设置最小宽度
        const adjustedWidth = average + extraSpace;
        const finalWidth = Math.max(adjustedWidth, minWidth);
        
        console.log('最终宽度(平均宽度模式):', finalWidth, 'px');
        return `${finalWidth}px`;
      }
    }

Vue2中的mixins写法

export const textWidthMixin = {
  methods: {
    /**
     * 根据传入的文本计算宽度
     * @description 计算文本宽度,可选择平均宽度或最大宽度模式,保留两位小数
     * @param texts 文本数组  例如 ['文本1', '文本2', '文本3']
     * @param font 文本信息 例如 '14px sans-serif'
     * @param extraSpace 额外空间,默认值为100px
     * @param minWidth 最小宽度,默认值为100px
     * @param useMaxWidth 是否使用最大宽度模式,默认false使用平均宽度
     * @returns 返回计算后的宽度,单位为px
     */
    calculateTextWidth(texts, {font = '14px sans-serif', extraSpace = 50, minWidth = 100, useMaxWidth = false} = {}) {        
      // 创建离屏canvas用于测量文本宽度
      const canvas = document.createElement('canvas');
      const context = canvas.getContext('2d');
      
      // 设置字体
      context.font = font;
      
      // 计算每个文本的宽度
      const widths = texts.map(text => {
        const width = context.measureText(text).width;
        return width;
      });
      
      if (useMaxWidth) {
        // 最大宽度模式:取所有宽度中的最大值加上额外空间
        const maxWidth = Math.max(...widths) + extraSpace;
        const finalWidth = Math.max(maxWidth, minWidth);
        console.log('最终宽度(最大宽度模式):', finalWidth, 'px');
        return `${finalWidth}px`;
      } else {
        // 平均宽度模式:移除一个最大值和一个最小值后取平均
        // 排序宽度数组(从小到大)
        widths.sort((a, b) => a - b);
        
        // 移除一个最大值和一个最小值
        const filteredWidths = widths.slice(1, widths.length - 1);
        
        // 计算过滤后的总宽度
        const sum = filteredWidths.reduce((total, width) => total + width, 0);
        
        // 计算平均值,至少保留两位小数
        const average = filteredWidths.length > 0 
          ? parseFloat((sum / filteredWidths.length).toFixed(2)) 
          : 0;
        
        // 添加额外空间并设置最小宽度
        const adjustedWidth = average + extraSpace;
        const finalWidth = Math.max(adjustedWidth, minWidth);
        
        console.log('最终宽度(平均宽度模式):', finalWidth, 'px');
        return `${finalWidth}px`;
      }
    }
  }
}  

Vue3中hook使用

import { ref, reactive, computed } from 'vue'

export const useTextWidth = () => {
  // 响应式状态
  const state = reactive({
    texts: [],
    font: '14px sans-serif',
    averageWidth: '0px'
  })

  // 计算属性,类似Vue2的计算属性
  const displayWidth = computed(() => {
    return `计算结果: ${state.averageWidth}`
  })

  /**
   * 根据传入的文本宽度计算平均宽度
   * @description 计算平均文本宽度,移除一个最大值和一个最小值,保留两位小数
   * @param texts 文本数组  例如 ['文本1', '文本2', '文本3']
   * @param font 文本信息 例如 '14px sans-serif'
   * @returns 返回计算后的平均宽度,单位为px
   */
  const calculateAverageTextWidth = (texts = state.texts, font = state.font) => {        
    // 创建离屏canvas用于测量文本宽度
    const canvas = document.createElement('canvas');
    const context = canvas.getContext('2d');
    
    // 设置字体
    context.font = font;
    
    // 计算每个文本的宽度
    const widths = texts.map(text => {
      const width = context.measureText(text).width;
      return width;
    });
    
    // 排序宽度数组(从小到大)
    widths.sort((a, b) => a - b);
    
    // 移除一个最大值和一个最小值
    const filteredWidths = widths.slice(1, widths.length - 1);
    
    // 计算过滤后的总宽度
    const sum = filteredWidths.reduce((total, width) => total + width, 0);
    
    // 计算平均值,至少保留两位小数
    const average = filteredWidths.length > 0 
      ? parseFloat((sum / filteredWidths.length).toFixed(2)) 
      : 0;
    
    // 添加额外空间并设置最小宽度
    const adjustedWidth = average + 100;
    const finalWidth = Math.max(adjustedWidth, 100);
    
    // console.log('最终宽度:', finalWidth, 'px');
    return `${finalWidth}px`;
  }

  // 更新状态的方法
  const updateTexts = (newTexts) => {
    state.texts = newTexts
    state.averageWidth = calculateAverageTextWidth(newTexts, state.font)
  }

  const updateFont = (newFont) => {
    state.font = newFont
    state.averageWidth = calculateAverageTextWidth(state.texts, newFont)
  }

  // 初始化计算
  onMounted(() => {
    if (state.texts.length > 0) {
      state.averageWidth = calculateAverageTextWidth()
    }
  })

  return {
    // 状态
    state,
    displayWidth,
    
    // 方法
    calculateAverageTextWidth,
    updateTexts,
    updateFont
  }
}

本文链接:https://blog.smallhao.fun/?id=29 转载需授权!

分享到:

Chen’Blog版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

VueJavaScript
安装依赖报错 前端 Websocket 公共方法封装

游客 回复需填写必要信息
召唤伊斯特瓦尔