Vue移动端项目二次封装原生table组件,支持表头/数据动态配置;作用域插槽、render函数渲染某列数据等功能,任何端都可以通用

一、最终效果

二、参数配置

1、代码示例:

<t-table :columns="columns" :data="tableData" max-height="calc(100vh - 170px)"/>

2、配置参数(t-table Attributes)

参数 说明 类型 默认值
columns 表头配置项 Array []
data 数据源 Array []
max-height 固定表头 String -
height 表格高度 String 100%
emptyText 无数据文案 String ‘暂无数据’

2-1、columns配置项

参数 说明 类型 默认值
label 表头名称 String -
prop 数据字段 String -
width 列宽 String -
align 对齐方式 (可选值:left/center/right) String left
render render函数 function -
slotName 作用域插槽 String -

3、events 事件

事件名称 说明 回调参数
rowClick 行点击事件 当前行数据row,当前所在行rowIndex

三、源码

<template>
  <div class="t-table-wrapper">
    <div
      class="t-table-scroll"
      :style="{ height: height, maxHeight: maxHeight }"
    >
      <table class="t-table">
        <colgroup>
          <col
            v-for="(col, idx) in columns"
            :key="idx"
            :style="{
              width: col.width
                ? typeof col.width === 'number'
                  ? col.width + 'px'
                  : col.width
                : 'auto',
            }"
          />
        colgroup>
        <thead>
          <tr>
            <th
              v-for="(col, idx) in columns"
              :key="idx"
              :style="{
                textAlign: col.align ? col.align : 'left',
                position: 'sticky',
                top: '-2px',
                background: '#f7f7f7',
                zIndex: 2,
              }"
            >
              {{ col.label }}
            th>
          tr>
        thead>
        <tbody>
          <template v-if="data && data.length">
            <tr
              v-for="(row, rowIndex) in data"
              :key="rowIndex"
              @click="rowClick(row, rowIndex)"
            >
              <td
                v-for="(col, colIndex) in columns"
                :key="colIndex"
                :style="{
                  textAlign: col.align ? col.align : 'left',
                  width: col.width
                    ? typeof col.width === 'number'
                      ? col.width + 'px'
                      : col.width
                    : 'auto',
                }"
              >
                <template v-if="col.slotName">
                  <slot :name="col.slotName" :scope="row">slot>
                template>
                <template v-if="col.render">{{
                  col.render(row, rowIndex)
                }}template>
                <template v-if="!col.render && !col.slotName">{{
                  row[col.prop]
                }}template>
              td>
            tr>
          template>
          <template v-else>
            <tr>
              <td
                :colspan="columns.length"
                style="text-align: center; color: #999; padding: 20px 0"
              >
                {{ emptyText }}
              td>
            tr>
          template>
        tbody>
      table>
    div>
  div>
template>

<script>
export default {
  name: "TTable",
  props: {
    columns: {
      type: Array,
      required: true,
    },
    data: {
      type: Array,
      required: true,
    },
    height: {
      type: String,
      default: "100%",
    },
    maxHeight: {
      type: String,
      default: "",
    },
    emptyText: {
      type: String,
      default: "暂无数据",
    },
  },
  methods: {
    rowClick(row, rowIndex) {
      // console.log("Row clicked:", row, rowIndex);
      this.$emit("row-click", row, rowIndex);
    },
  },
};
script>

<style lang="scss" scoped>
.t-table-wrapper {
  width: 100%;
  overflow-x: auto;
  .t-table-scroll {
    min-width: 100%;
    overflow-x: auto;
    .t-table {
      width: max-content;
      border-collapse: collapse;
      min-width: 100%;
      th,
      td {
        padding: 10px 8px;
        border: 1px solid #eee;
        text-align: left;
        white-space: nowrap;
        font-size: 14px;
        white-space: normal; // 支持换行
        word-break: break-all; // 长单词或长内容换行
      }
      th {
        background: #f7f7f7;
        font-weight: bold;
      }
    }
  }
}
style>


相关文章

基于ElementUi再次封装基础组件文档


vue3+ts基于Element-plus再次封装基础组件文档

你可能感兴趣的:(Vue移动端项目二次封装原生table组件,支持表头/数据动态配置;作用域插槽、render函数渲染某列数据等功能,任何端都可以通用)