vue.js的原生轻量table组件,最多支持双层title组件,可以解决应付使用框架table带来的卡顿慢现象和处理大数据表格使用

本文介绍了一款Vue.js的原生轻量级Table组件,该组件特别设计用于处理大数据表格,能有效避免框架自带table组件带来的卡顿问题,支持双层标题,提高用户体验。

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

<template>
  <div ref="table" class="tableBox">
    <table class="sixTable" border="1" id="table">
      <thead class="titles" v-if="columns.length !== 0">
        <tr>
          <th
            v-for="t in columns"
            :colspan="t.children ? t.children.length:1 "
            :rowspan="t.children ? 1: 2"
            :key="t.key"
          >
            <div :style="{width: t.width ? t.width +'px'  : '' }" class="content">{{t.title}}</div>
          </th>
        </tr>

        <tr>
          <th v-for="i in thChildren" :rowspan="i._children ? 1: 2" :key="i.key">
            <div :style="{width: i.width ? i.width +'px'  : '' }" class="content">{{i.title}}</div>
          </th>
        </tr>
      </thead>

      <tbody class="tbody" v-if="datas.length !== 0">
        <tr
          v-for="(item,index) in datas"
          :style="{background:backgroundColor ?  color(index) : ''  }"
          :key="index"
        >
          <td v-for="i in rowtd " :key="i.key">
            <div class="content" :style="{textAlign:i.align , width:_tdWidth(i)  }">
              <div v-if="i.key === 'index'">{{index+1 }}</div>
              <div v-if="i.slot ? false:true">{{item[i.key]}}</div>
              <slot :name="i.slot" :row="item" :index="index" />
            </div>
          </td>
        </tr>
      </tbody>
      <!-- v-if="item[i.key] === null ? false : true"  此处可以开启是否展示td内的数据    --> 
      <tbody v-else>
        <tr>
          <td :colspan="rowtd.length ">
            <div class="nodata">暂无数据</div>
          </td>
        </tr>
      </tbody>
    </table>
  </div>
</template>

<script>
export default {
  props: {
    datas: {
      type: Array,
      default: () => []
    },
    // 入参举例 :key一定要传!!! slot 可以选择不传  type为index默认就是行序号
    //[{
    //     type: 'index',
    //     title: '序号',
    //     width: 60,
    //     key: 'index',
    //     align: 'center'
    // },
    // {
    //     title: '校验结果',
    //     key: 'status',
    //     slot: 'status',
    //     width: 100,
    //     height: 30,
    //     align: 'center',
    //     children:[ {
	//			key:'fwfwfw',
	//			title:'fwfwfw',
	//		} ]
    // },]

    columns: {
      type: Array,
      default: () => []
    },
    // 是否使用隔行变色
    backgroundColor: Boolean
  },

  data() {
    return {
      color: index => (index % 2 == 0 ? "rgba(248,250,253,1)" : "#fff")
    };
  },

  methods: {
    _tdWidth(i) {
      const res = this.columns.find(e => e.key === i.key);
      if (res && res.width) {
        return res.width + "px";
      }
    }
  },

  computed: {
    thChildren: {
      get() {
        let arr = [];
        this.columns.forEach(e => {
          if (e.children) {
            e.children.forEach(i => {
              i._children = true;
              arr.push(i);
            });
          }
        });
        return arr;
      }
    },

    rowtd: {
      get() {
        let arr = [];
        this.columns.forEach(e => {
          if (e.children) {
            e.children.forEach(i => {
              arr.push(i);
            });
          } else {
            arr.push(e);
          }
        });
        return arr;
      }
    }
  }
};
</script>
<style lang="less" scoped>

.tableBox {
  overflow: auto;
  border-left: 1px solid rgba(236, 241, 248, 1);
  border-right: 1px solid rgba(236, 241, 248, 1);
}

.sixTable {
  border-collapse: collapse;
  border: 1px solid rgba(236, 241, 248, 1);
  border-left: none;
  border-right: none;
  font-size: 14px;
  font-weight: normal;

  .titles {
    color: #43454d;
    font-family: PingFangSC-Semibold, PingFang SC;
    font-weight: 600;
    color: #585858;
  }

  .tbody {
    font-size: 14px;
    font-family: PingFangSC-Regular, PingFang SC;
    font-weight: 400;
    color: rgba(88, 88, 88, 1);
  }
}

.sixTable .content {
  padding: 8px;
  box-sizing: border-box;
  position: relative;
}

.sixTable .nodata {
  padding: 18px;
  text-align: center;
}
</style>

最终的效果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值