Vxe-table 组件封装(一) —— 添加render方法

5,819 阅读2分钟

为了能让列表的加载与滚动都不再卡顿,需要在公司UI里封装一个vxe-table为基础的Table组件. 主要是使用了vxe-table的虚拟滚动功能

下方是vxe-table的一个简易demo,我们能看到它不像常用table组件,columns不是传入数组,而是逐个单独写的。

ps: vxe-grid支持传入columns, 但是可自定义配置比vxe-table + vxe-column少,所以没选用vxe-grid.

<vxe-table 
  :data="tableData"  //列表数组
 >
  //每个单独定义的列
  <vxe-column type="seq" title="序号" width="60" fixed="left"></vxe-column> 
  <vxe-column field="name" title="Name" width="300"></vxe-column>
  <vxe-column field="role" title="Role" width="300"></vxe-column>
  <vxe-column field="sex" title="Sex" width="300"></vxe-column> 
  <vxe-column field="date" title="Date" width="300"></vxe-column> 
  <vxe-column field="address" title="Address" fixed="right" width="300"></vxe-column> 
</vxe-table>

效果: image.png

封装后的组件要支持接收columns数组,不能再让业务线去自己写一行一行的vxe-columns 所以基础版本是这样的:

//xTable.vue
<template>
    <vxe-table
      ref="vxeTable"
      :data="tableData"
      v-bind.sync="tbConfig"  //绑定属性
      @cell-click="params => $emit('cell-click', params)">  //向外暴露事件

      //空数据时
      <template #empty> <Empty/> </template>

      <vxe-column
        v-for="item in tableColumns"
        :key="item.key"
        v-bind.sync="item"    // 绑定属性
        >
        <template #default="scope">
          <!-- 默认 -->
          <span v-if="!item.slot && !item.render">{{ scope.row[item.field] }}</span>

          <!-- 自定义插槽 -->
          <slot :name="item.slot" v-if="item.slot" :scope="scope"></slot>

          <!-- 渲染形式 -->
          <renderer v-if="item.render && !item.slot" :renderContent="item.render" :scope="scope"></renderer>
        </template>

      </vxe-column>
    </vxe-table>
  </template>

组件接收的传入数据:

props: {
    // 表格数据源
    tableData: {
      type: Array,
      default: () => []
    },
    // 表格列项
    columns: {
      type: Array,
      default: () => []
    },
    //vxe-table的属性 可参考vxe-table的官方文档: https://vxetable.cn/v3/#/table/api
    tbConfig: {
      type: Object,
      default:  () =>{ return {}}
    }
  },

//传入的columns的例子
columns: [
                {
                    type: "checkbox",  //类型-复选框、单选框、展开列
                    field: "name",     //显示的数据字段,类似iview table的 ‘key’
                    title: "姓名",     //表头名称
                    align: "left"      //对齐方式
                    visible: false     //是否展示
                    fixed: 'left'      //固定位置
                    render: (h, {row, rowIndex}) => {
                      return h('div',{}...)
                      //或者
                      return (
                          <div>...</div>
                        )
                    },
                    // 表头
                    renderHeader: (h, column) => {
                       return h('div',{}...)
                       //或者
                       return (
                          <div>...</div>
                       )
                    }
                    ...
                }
                ...
          ]
//可选属性参考vxe-table的官方文档: https://vxetable.cn/v3/#/column/api

关于renderer组件:

由于我们很多的现有业务使用的是iview table的render,所以要为这个列表组件也添加render功能.

iview table关于render功能的描述:

image.png

renderer组件代码:
<script>
export default {
    name: "renderer",
    props: {
        renderContent: {
            type: Function
        },
        scope: {
            type: Object
        }
    },

    render: function(h) {
        const { renderContent, scope } = this;
        return renderContent(h, scope);
    }  
};
</script>

使用示例:

<template>
  <div>
      <xTable
          ref="bndTb"
          :source="source"
          :columns="columns"
          :tbProps="tbProps"
          @cellClick="cellClick"
      >
      </xTable>
  </div>
</template>

<script>
import xTable from './xTable.vue'
export default {
  data() {
      return {
          tbProps: {
              columnConfig: {
                  sortable: false
              },
              rowConfig: {
                  keyField: "id",
                  // 行经过高亮
                  isHover: true
              }
          },
          columns: [
              {
                  type: "checkbox",
                  field: "name",
                  title: "姓名",
                  width: 200,
                  align: "left"
              },
              {
                  field: "age",
                  title: "年龄",
                  align: "center"
              },
              {
                  field: "sex",
                  title: "性别",
                  render: (h, { row })=>{
                    return (
                          <div>性别:{ row.sex } </div>
                    )
                  }
              }
          ],
          source: [
              { id: 1, name: '张三', age: '17', sex: '男' },
              { id: 2, name: '李四', age: '18', sex: '女' },
              { id: 3, name: '李四', age: '18', sex: '女' },
              { id: 4, name: '李四', age: '18', sex: '女' },
          ]
      }
  },
  methods: {
      cellClick(e) {
        console.warn('e~~~~~~: ', e)
      },
  },
  components: { xTable }
};
</script>

</script>

image.png

以上是支持了render写法的版本, 后面会逐步更新复合表头、拖拽和高度自适应等功能.