Vue2表格(Table)

39 篇文章 5 订阅

Vue3表格(Table)

自定义传入:

  • 表格列的配置项(columns)
  • 表格数据数组(dataSource)
  • 分页器,为false时不展示和进行分页(pagination)
  • 只有一页时是否隐藏分页器(hideOnSinglePage)
  • 数据总数(total),默认为0
  • 页面是否加载中(loading),默认为false

整体样式模仿ant-design,效果图如下:

1.初始加载数据时的表格样式:

2.有数据并带分页时的表格样式:

3.有数据无分页时的表格样式:

 4.无数据时的表格样式:

包含加载中组件分页组件的表格Table

①创建带分页表格组件Table.vue:

<template>
  <div class="m-table-wrap">
    <table>
      <thead>
        <tr>
          <th :width="item.width" v-for="(item, index) in columns" :key="index">
            {{ item.title }}
          </th>
        </tr>
      </thead>
      <tbody class="m-body">
        <tr v-show="loading">
          <Spin class="m-loading" :colspan="columns.length" />
        </tr>
        <tr v-show="!total">
          <td class="m-empty" :colspan="columns.length">
            <svg class="u-empty-icon" viewBox="0 0 64 41" xmlns="http://www.w3.org/2000/svg">
              <g transform="translate(0 1)" fill="none" fillRule="evenodd">
                <ellipse fill="#F5F5F5" cx="32" cy="33" rx="32" ry="7"></ellipse>
                <g fillRule="nonzero" stroke="#D9D9D9">
                  <path d="M55 12.76L44.854 1.258C44.367.474 43.656 0 42.907 0H21.093c-.749 0-1.46.474-1.947 1.257L9 12.761V22h46v-9.24z"></path>
                  <path
                  d="M41.613 15.931c0-1.605.994-2.93 2.227-2.931H55v18.137C55 33.26 53.68 35 52.05 35h-40.1C10.32 35 9 33.259 9 31.137V13h11.16c1.233 0 2.227 1.323 2.227 2.928v.022c0 1.605 1.005 2.901 2.237 2.901h14.752c1.232 0 2.237-1.308 2.237-2.913v-.007z"
                  fill="#FAFAFA"
                  ></path>
                </g>
              </g>
            </svg>
            <p class="u-empty-desc">暂无数据</p>
          </td>
        </tr>
        <tr v-for="(data, index) in dataSource" :key="index">
          <td v-for="(col, ind) in columns" :key="ind" :title="data[col.dataIndex]">
            <slot v-if="col.slot" v-bind:data="data" :name="col.slot">{{ data[col.dataIndex] || '--' }}</slot>
            <span v-else>{{ data[col.dataIndex] || '--' }}</span>
          </td>
        </tr>
      </tbody>
    </table>
    <Pagination
      @change="changePage"
      :current="pagination.p"
      :pageSize="pagination.pageSize"
      :total="total"
      :hideOnSinglePage="hideOnSinglePage"
      :showQuickJumper="true"
      :showTotal="true"
      placement="right"
      v-if="pagination && total" />
  </div>
</template>
<script>
import Pagination from './Pagination'
import Spin from './Spin'
export default {
  name: 'Table',
  components: {
    Pagination,
    Spin
  },
  props: {
    columns: { // 表格列的配置项
      type: Array,
      default: () => {
        return []
      }
    },
    dataSource: { // 表格数据数组
      type: Array,
      default: () => {
        return []
      }
    },
    pagination: { // 分页器,为false时不展示和进行分页
      type: [Boolean, Object],
      default: false
    },
    hideOnSinglePage: { // 只有一页时是否隐藏分页器
      type: Boolean,
      default: false
    },
    total: { // 数据总数
      type: Number,
      default: 0
    },
    loading: { // 页面是否加载中
      type: Boolean,
      default: false
    }
  },
  methods: {
    changePage (pager) { // 分页器回调
      this.$emit('change', pager)
    }
  }
}
</script>
<style lang="less" scoped>
.m-table-wrap {
  color: rgba(0, 0, 0, 0.65);
  font-size: 14px;
  line-height: 1.5;
  table {
    table-layout: fixed;
    width: 100%;
    text-align: left;
    border-radius: 4px 4px 0 0;
    border-collapse: separate;
    border-spacing: 0;
    thead tr th {
      padding: 16px;
      color: rgba(0, 0, 0, 0.85);
      font-weight: 500;
      text-align: left;
      background: #fafafa;
      border-bottom: 1px solid #e8e8e8;
      transition: background .3s ease;
      &:first-child {
        border-top-left-radius: 4px;
      }
      &:last-child {
        border-top-right-radius: 4px;
      }
    }
    .m-body {
      position: relative;
      .m-loading {
        position: absolute;
        width: 100%;
        height: 100%;
      }
      .m-empty {
        padding: 48px 16px;
        color: rgba(0, 0, 0, 0.25);
        font-size: 14px;
        text-align: center;
        background: #fff;
        border-bottom: 1px solid #e8e8e8;
        border-radius: 0 0 2px 2px;
        .u-empty-icon {
          width: 64px;
          height: 41px;
          margin-bottom: 8px;
        }
        .u-empty-desc {
          color: rgba(0, 0, 0, 0.25);
          font-size: 14px;
        }
      }
    }
    tbody tr {
      transition: background .3s;
      td {
        padding: 16px;
        border-bottom: 1px solid #e8e8e8;
        transition: background .3s;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
      }
      &:hover {
        background: #e6f7ff;
      }
    }
  }
}
</style>

 ②在要使用的页面引入:

<Table
      :columns="columns"
      :dataSource="tableData"
      :pagination="{
        p: queryParams.p,
        pageSize: queryParams.pageSize
      }"
      :hideOnSinglePage="false"
      :total="total"
      :loading="loading"
      @change="onChangeTable"
    >
      <!-- 配置指定列数据 -->
      <!-- <template #name="{ data: record }">
        hello {{ record.name }}
      </template>
      <template v-slot:job="{ data: record }">
        hi {{ record.job }}
      </template> -->
</Table>
import Table from '@/components/Table'
components: {
    Table
}
loading: false,
total: 10,
queryParams: {
	pageSize: 3,
	p: 1,
	mod: 'search'
},
columns: [
        {
          title: '名字',
          width: 100,
          dataIndex: 'name',
          slot: 'name'
        },
        {
          title: '年龄',
          width: 100,
          dataIndex: 'age'
        },
        {
          title: '职业',
          width: 100,
          dataIndex: 'job',
          slot: 'job'
        },
        {
          title: '性别',
          width: 100,
          dataIndex: 'sex'
        },
        {
          title: '地址',
          width: 120,
          dataIndex: 'address'
        }
],
tableData: [
        {
          name: 'Stephen',
          age: 30,
          job: 'player',
          sex: '男',
          address: 'CaliforniaCaliforniaCaliforniaCaliforniaCaliforniaCalifornia'
        },
        {
          name: 'Leo',
          age: 36,
          job: 'actor',
          sex: '男',
          address: 'LA'
        },
        {
          name: 'Mr.Dear',
          age: 23,
          job: 'boy',
          sex: '男',
          address: 'Beijing'
        },
        {
          name: 'superman',
          age: 32,
          job: 'boy',
          sex: '男',
          address: 'US'
        }
]
onChangeTable (pagination) {
      console.log('pagination:', pagination)
      this.queryParams.p = pagination.p
      this.queryParams.pageSize = pagination.pageSize
      this.getData()
},
getData () {
      this.tableLoading = true
      // 调用分页接口获取列表数据
}
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值