简单封装el-popover用于el-table-column里渲染

博客介绍了如何在Vue项目中针对el-table-column的文本溢出需求,通过封装el-popover组件来实现动态弹框展示全部文本。内容包括利用全局样式处理文本判断和显示,以及在数据集中管理相关信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

单行或多行文本溢出显示省略号,是很常见的需求。
然后今天遇到复杂点的需求,在el-table里有些单元格文本长,有些短,需要判断是否溢出,溢出时弹框显示所有文本。
判断文本是否溢出,参考此文 https://juejin.im/post/5d7798dc6fb9a06acc00af6c
但是,在el-table里,单元格是el-table-column渲染的,show-overflow-tooltip只支持单行,而el-popover好像没有提供相关处理逻辑,所以需要简单封装一下,以便在el-table-column 里渲染。

没有时间整理文字,暂记。

<template>
  <el-popover
    trigger="hover"
    placement="top"
    popper-class="popover-when-ellipsis"
    :title="title"
    :content="popperContent"
    :disabled="disabled"
    v-bind="$attrs"
  >
    <slot name="content"></slot>
    <div slot="reference" ref="reference" :class="ellipsisClass">
      {{ content }}
    </div>
  </el-popover>
</template>

<script>
export default {
  name: 'popover-when-ellipsis'
  /**
   * @props title: el-popover组件的标题  content: 要显示的内容 slot传入的DOM优先,覆盖掉content
   *        multiline: 2行或3行,不传就默认是单行
   */
  props: {
    title: String,
    content: {
      type: String,
      required: true
    },
    multiline: {
      type: String,
      validator: (val) => ['2', '3'].indexOf(val) > -1
    }
  },

  data() {
    return {
      disabled: true,
      timer: null
    }
  },

  computed: {
    ellipsisClass() {
      return !this.multiline
        ? 'text-ellipsis'
        : 'text-ellipsis-' + this.multiline
    },
    popperContent() {
      // 看el-popover源码,传不传content这个prop主要是影响样式,传了会多一个el-popover--plain类名,padding更大
      if (!this.$slots.content) return this.content
      return undefined
    }
  },

  methods: {
    // 查看DOM可以发现Vue-popper里的tooltip元素是始终渲染的,disabled只是控制事件的绑定和解绑
    // 事件触发显示popper,是把tooltip元素appendChild移动到body下,动态定位并display: block显示
    // judge方法判断是否需要popper
    judge() {
      const el = this.$refs.reference
      if (!this.multiline) {
        this.disabled = !(el.clientWidth < el.scrollWidth) // disabled反逻辑
      } else {
        this.disabled = !(el.clientHeight < el.scrollHeight)
      }
    },

    // resize事件像scroll事件一样,也是会连续触发的
    throttle() {
      if (this.timer) {
        clearTimeout(this.timer)
      }
      this.timer = setTimeout(() => {
        this.judge()
      }, 500)
    }
  },

  mounted() {
    this.judge()
    window.addEventListener('resize', this.throttle)
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.throttle)
  },
  // 表格数据翻页时,在el-table-column里渲染的只有数据内容改变,不会重新触发mounted,导致bug
  updated() {
    this.judge()
  }
}
</script>

全局样式里需要提供 .text-ellipsis .text-ellipsis-2 .text-ellipsis-3 以及 popover-when-ellipsis 四个类样式。

然后,就可以方便地进行循环渲染了。

<el-table-column
    v-for="col in shownCols"
        :key="col.prop"
        :label="col.label"
        :width="col.width"
        :min-width="col.minWidth"
        :formatter="col.formatter"
    >
          <template slot-scope="scope">
            <popover-when-ellipsis
              v-if="colsNeedPopper.includes(col.prop)"
              :title="col.label"
              :content="scope.row[col.prop]"
              multiline="3"
            />
            <span v-else>{{ scope.row[col.prop] }}</span>
      </template>
 </el-table-column>

data 里可以集中管理数据,在 shownCols 数组里。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值