Ant Design of Vue Table二次封装采用集成 vue-draggable-resizable 来实现可伸缩列

前言

在Vue的Table组件中,实现可伸缩列,如果你使用的是Element-Ui那么这是一个现成的功能,如果你使用的是ant-design-vue,那么是需要集成一个vue-draggable-resizable插件但是官网示例的代码并不能直接使用,以下是封装的a-table组件

1、先引入vue-draggable-resizable(先安装依赖)

import Vue from 'vue'
import VueDraggableResizable from 'vue-draggable-resizable'
Vue.component('vue-draggable-resizable', VueDraggableResizable)

2、在Table添加 components属性

 <Table
      v-if="!$slots.table"
      v-bind="antTableOpt"
      :components="components"
      :bordered="tableOpt.bordered"
    ></Table>

3、添加样式(最坑的地方)

 // 实现可伸缩列样式
  .resize-table-th {
    position: relative;
    .table-draggable-handle {
      height: 100% !important;
      bottom: 0;
      position: absolute;
      left: auto !important;
      transform: none !important;
      right: -5px;
      z-index: 100 !important;
      cursor: col-resize;
      touch-action: none;
    }
  }

4、完整代码

<template>
  <div class="W_table">
    <div class="header_wrap">
      <h3>
        {{title}}
        <slot name="title" />
      </h3>
      <div class="header_right_wrap">
        <slot name="btn" />
      </div>
    </div>
    <slot name="table" />
    <Table
      v-if="!$slots.table"
      v-bind="antTableOpt"
      :components="components"
      :bordered="tableOpt.bordered"
    ></Table>
    <Pagination
      v-if="pagination !== null"
      class="pagination"
      :defaultCurrent="1"
      :pageSize="pagination.pageSize"
      :current="pagination.current"
      @change="(current, pageSize) => $emit('paginationChange', current, pageSize)"
      :total="pagination.total && pagination.total >= pagination.pageSize ? pagination.total : pagination.pageSize"
    ></Pagination>
  </div>
</template>
<script>
import { Table, Pagination } from 'ant-design-vue'
// import OptComponent from './OptComponent'
import Vue from 'vue'
import VueDraggableResizable from 'vue-draggable-resizable'
Vue.component('vue-draggable-resizable', VueDraggableResizable)
export default {
  name: 'WTable',
  components: {
    Table,
    Pagination
  },
  props: {
    title: {
      type: String,
      default: ''
    },
    // 表头信息
    columns: {
      type: Array,
      default: () => ([])
    },
    // 表格数据源
    dataSource: {
      type: Array,
      default: () => ([])
    },
    // 分页信息
    pagination: {
      type: [Object, null],
      default: null
    },
    // 继承Ant Design of Vue Table属性
    tableOpt: {
      type: Object,
      default: () => ({})
    }
  },
  computed: {
    antTableOpt () {
      const { columns, dataSource, tableOpt } = this
      return { rowKey: 'id', size: 'middle', ...tableOpt, columns, dataSource, pagination: false }
    },
    components () {
    // Ant Design of Vue Table有边框才有此功能
      if (this.tableOpt.bordered) {
        return {
          header: {
            cell: (h, props, children) => {
              const { key, ...restProps } = props
              const col = this.columns.find(col => {
                const k = col.dataIndex || col.key
                return k === key
              })

              if (!col || !col.width) {
                return h('th', { ...restProps }, [...children])
              }

              const dragProps = {
                key: col.dataIndex || col.key,
                class: 'table-draggable-handle',
                attrs: {
                  w: 10,
                  x: col.width,
                  z: 1,
                  axis: 'x',
                  draggable: true,
                  transform: 'none',
                  resizable: false
                },
                on: {
                  dragging: (x, y) => {
                    col.width = Math.max(x, 90)
                  }
                }
              }
              const drag = h('vue-draggable-resizable', { ...dragProps })
              return h('th', { ...restProps, class: 'resize-table-th' }, [...children, drag])
            }
          }
        }
      } else {
        return {}
      }
    }
  }
}
</script>
<style lang="scss">
.w_table {
  .header_wrap {
    display: flex;
    align-items: center;
    margin-bottom: 24px;
    h3 {
      flex-grow: 1;
      margin: 0;
      font-size: 20px;
      line-height: 28px;
      text-align: left;
    }
  }
  .ant-btn-link {
    height: 16px;
  }
  .pagination {
    position: relative;
    margin-top: 16px;
    padding: 0;
    text-align: right;
  }
  .ant-table-body {
    table {
      overflow: hidden;
    }
  }
  // 实现可伸缩列样式
  .resize-table-th {
    position: relative;
    .table-draggable-handle {
      height: 100% !important;
      bottom: 0;
      position: absolute;
      left: auto !important;
      transform: none !important;
      right: -5px;
      z-index: 100 !important;
      cursor: col-resize;
      touch-action: none;
    }
  }
}
</style>

页面使用

<w-table :columns="columns" :dataSource="sourceData" :tableOpt="{bordered:true}" />

最后注意

columns中必须有dataIndex和width且width必须是Number类型;不然不会生效

组件地址

gitHub组件地址

gitee码云组件地址

相关文章

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

评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wocwin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值