vue自定义表格tooltip

<template>
  <view :id="uniId" style="position: relative;">
    <view v-if="textContent" class="text-content">{{ textContent }}</view>
    <view v-show="tooltipContent" class="child" :id="`${uniId}-child`">{{ tooltipContent }}</view>
    <scroll-view scroll-x="true" class="body" @scroll="mouseleave()">
      <u-table class="table" :style="{'width': tableWidth}" color="#000000cc" fontSize="24">
        <u-tr>
          <u-th v-for="item in tableColumns" :key="item.prop" :style="{'textAlign': item.align || 'center'}" :width="item.cellsWidth">{{ item.label }}</u-th>
        </u-tr>
        <u-tr v-for="(row, index) in tableData" :key="index">
          <u-td v-for="item in tableColumns" :key="item.prop"
            :style="{...tdStyle(item), 'textAlign': item.align || 'center'}" :width="item.cellsWidth">
            <span v-if="item.type === 'index'">{{ index + 1 }}</span>
            <span v-else :id="`${item.prop}-${index}`" @mouseleave="mouseleave()" @mouseenter="mouseenter($event, row[item.prop], `${item.prop}-${index}`)">{{ row[item.prop] }}</span>
          </u-td>
        </u-tr>
      </u-table>
    </scroll-view>
  </view>
</template>

<script>
export default {
  name: 'leader-table',
  props: {
    // 表格宽度
    tableWidth: {
      type: String,
      default: '100%'
    },
    // 单元格宽度
    cellsWidth: {
      type: String,
      default: '100%'
    },
    // 表格上方文本内容
    textContent: {
      type: String,
      default: ''
    },
    // 单元格样式
    tdStyle: {
      type: Function,
      default: () => {}
    },
    tableColumns: {
      type: Array,
      default: () => []
    },
    tableData: {
      type: Array,
      default: () => []
    }
  },
  
  data() {
    return {
      // 生成唯一标识,方便每个表格组件定位
      uniId: Math.floor(Math.random() * Date.now()).toString(36),
      tooltipContent: ''
    }
  },
  
  methods: {
    mouseleave () {
      this.tooltipContent = ''
    },
    mouseenter (event, content, tdId) {
      this.tooltipContent = content
      const TdContent = document.getElementById(tdId)
      // 内容的宽度超出范围则显示tooltip
      this.tooltipContent = TdContent.scrollWidth > TdContent.clientWidth ? content : ''
      this.$nextTick(_ => {
        const parent = document.getElementById(this.uniId)
        const child = document.getElementById(`${this.uniId}-child`)
        let x = event.clientX - parent.offsetLeft - child.offsetWidth
        let y = event.pageY - parent.offsetTop - child.offsetHeight
        if (x < 0) {
          x = 0
        } else if (x + child.offsetWidth > parent.offsetWidth) {
          x = parent.offsetWidth - child.offsetWidth
        }
        if (y < 0) {
          y = 0;
        } else if (y + child.offsetHeight > parent.offsetHeight) {
          y = parent.offsetHeight - child.offsetHeight
        }

        child.style.left = x + "px"
        child.style.top = y + "px"
      })
    }
  }
}
</script>

<style lang='scss' scoped>
.text-content {
  text-size-adjust: none;
  color: #0000008c;
  font-family: "PingFang SC";
  font-size: 20rpx;
  font-style: normal;
  font-weight: 400;
  line-height: normal;
  margin-bottom: 12rpx;
  margin-top: 18rpx;
  transform-origin: 0 0;
  white-space: nowrap;
}
.child {
  z-index: 1;
  position: absolute;
  color: white;
  font-size: 24rpx;
  padding: 4px;
  border-radius: 5px;
  background-color: #3c3c3c;
  max-width: 60%;
}

.table {
  border: none !important;
  ::v-deep.u-th {
    height: 61.33rpx !important;
    background-color: #E9EFFF;
    text-align: center;
    white-space: nowrap;
    border: none !important;
    flex-shrink: 0;
    color: #000000;
    font-size: 24rpx;
    font-weight: 700;
  }

  .u-td {
    display: flex !important;
    min-height: 66.67rpx !important;
    border: none !important;
    border-top: 1px solid #e5e5e5 !important;
    display: inline-block;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    text-overflow: ellipsis;
    span {
      display: inline-block;
      overflow: hidden;
      text-overflow: ellipsis;
    }
  }
}
</style>

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值