element-ui表格列宽度根据内容计算最小宽度min-width实现自适应参考

element ui的表格列

  • 遍历tableData 与表头,找出该列最长的字符max
  • 创建span标签计算最长字符所占宽度offsetWidth
  • 设置min-width属性(String类型)
    在组件渲染前计算出最小宽度,避免表格渲染过程宽度高度不稳定

其他方案参考:1. render-header 计算出宽度,然后渲染表头 2. header 插槽

<script>
/**
 * @description: 计算字符串的字节长度
 * @param {*} str
 * @return {*}
 */
function strByteLength(str) {
  if (!str) return 0
  let len = str.length
  for (let i = 0; i < str.length; i++) {
    if (str.charCodeAt(i) > 255) { len++ }
  }
  return len
}
/**
 * copy:
 * 1.超出长度可复制
 * 2. 设置canCopy = true
 */
import tableColumn from './TableColumn.vue'

export default {
  components: {
    tableColumn
  },
  render(h) {
    /**
     * 计算minWidth,是否可复制
     * minWidth/maxWidth   string eg: 60px
     */
    const { label, prop, formatter, sortable } = this.$attrs
    const tableData = this.$attrs['table-data']
    const minWidth = this.$attrs['min-width']
    const maxWidth = this.$attrs['max-width']
    
    const max = { str: '', length: 0 }
    const strs = tableData.map(item => {
      if (formatter && typeof formatter === 'function') {
        return formatter(null, null, item[prop], null)
      } else {
        return item[prop]
      }
    })
    strs.unshift(label)
    strs.forEach((item, i) => {
      const len = strByteLength(item)
      if (len > max.length) {
        max.str = item
        max.length = len
        max.i = i
      }
    })

    const span = document.createElement('span')
    span.innerHTML = max.str
    let width = document.body.appendChild(span).offsetWidth + 20
    // 如果有排序 排序箭头宽度24
    if (sortable) {
      span.innerHTML = label
      const labelWidth = document.body.appendChild(span).offsetWidth + 20 + 24
      if (labelWidth > width) width = labelWidth
    }
    document.body.removeChild(span)

    let minW = 60
    if (typeof minWidth === 'string') {
      minW = minWidth.match(/\d*/)[0] * 1
    }
    let maxW = 240
    if (typeof maxWidth === 'string') {
      maxW = maxWidth.match(/\d*/)[0] * 1
    }

    // 超出长度 可复制
    if (width >= maxW) {
      width = maxW
    }
    if (width <= minW) {
      width = minW
    }

    const reMinWidth = isNaN(width) ? '' : width + 'px'

    return (<tableColumn minWidth={reMinWidth} {...{ attrs: this.$attrs }}/>)
  }
}
</script>
// tableColumn.vue
// 根据需求扩展column
<template>
  <el-table-column v-if="type === 'index'" v-bind="$props" />
  <el-table-column v-else v-bind="{ ...$props, ...$attrs}" />
</template>

复制指令

clipboard: {
      // inserted 可获取父元素
      inserted: (el, binding) => {
        if (!binding.arg) return
        const button = document.createElement('a')
        button.innerHTML = '复制'
        button.className = 'cell-copy-btn hidden'
        button.handler = (e) => {
          e.stopPropagation()
          const content = el.innerText
          if (!content) {
            button.innerText = '无复制内容'
          }
          const textarea = document.createElement('textarea')
          textarea.readOnly = 'readonly'
          textarea.style.position = 'absolute'
          textarea.style.left = '-9999px'
          textarea.value = content
          document.body.appendChild(textarea)
          textarea.select()
          const res = document.execCommand('Copy')
          if (res) {
            button.innerText = '已复制'
            button.removeEventListener('click', button.handler, true)
            setTimeout(() => {
              button.innerText = '复制'
              button.addEventListener('click', button.handler, true)
            }, 2000)
          }
          document.body.removeChild(textarea)
        }
        button.addEventListener('click', button.handler, true)
        el.button = button
        el.parentNode.appendChild(el.button)

        el.showButton = () => {
          el.button.classList.remove('hidden')
        }
        el.hideButton = () => {
          el.button.classList.add('hidden')
        }

        const element = el.parentNode
        element.addEventListener('mouseenter', el.showButton, { passive: false })
        element.addEventListener('mouseleave', el.hideButton, { passive: false })
      },
      unbind(el, binding) {
        if (!binding.arg) return
        const element = el.parentNode
        if (element) {
          element.removeEventListener('mouseenter', el.showButton, { passive: false })
          element.addEventListener('mouseleave', el.hideButton, { passive: false })
        }
      }
    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值