在vue3中封装el-table和el-pagination

2,411 阅读2分钟

当你在一个项目中屡次使用表格和分页的时候,要写一大堆的el-table-column是不是很烦,接下来封装的该组件不仅可以替你减轻代码量,还不用自己再手动加分页哦,并且表格中支持自定义渲染的内容哦。

第一步:封装组件

第一步:项目的公共组件文件夹下面新建一个js文件,引入必要的组件和定义props

import { h, toRefs } from 'vue'
import { ElTable, ElTableColumn, ElPagination } from 'element-plus'
export default {
  name: 'PaginationTable',
  props: {
    tableClass: {
      type: String,
      default: ''
    },
    tableData: {
      type: Array,
      default() {
        return []
      }
    },
    columns: {
      type: Array,
      default() {
        return []
      }
    },
    hidePagination: {
      type: Boolean,
      default() {
        return false
      }
    },
    paginationEvents: {
      type: Object,
      default() {
        return {}
      }
    },
    tableEvents: {
      type: Object,
      default() {
        return {}
      }
    },
    pagination: {
      type: Object,
      default() {
        return {}
      }
    }
  },

第二步:setup中,使用h函数书写创建table和pagination的函数

setup(props, { emit, attrs }) {
    const createTable = () => {
      return h(
        ElTable,
        {
          ref: 'table',
          data: props.tableData,
          ...attrs,
          class: props.tableClass,
          ...props.tableEvents
        },
        () =>
          props.columns.map((columnProps, $index) => {
            const key = columnProps.key || columnProps.prop || $index
            const emptyFormatter = (row, column, cellValue, index) => {
              return !cellValue && cellValue !== 0 ? '--' : cellValue
            }
            if (!Reflect.has(columnProps, 'formatter')) {
              columnProps.formatter = emptyFormatter
            }
            if (columnProps?.hide) {
              return null
            } else {
              return h(
                ElTableColumn,
                {
                  ...columnProps,
                  ...props.tableColumnEvents,
                  key
                },
                columnProps.render
              )
            }
          })
      )
    }
    const createPagination = () => {
      if (props.hidePagination || !props.pagination) return
      const { pagination } = toRefs(props)
      pagination.value['currentPage'] =
        pagination.value['current-page'] || pagination.value.pageNum || pagination.value.pageNo
      return h(
        'div',
        {
          class: 'mt-20',
          style: 'text-align:right;'
        },
        h(ElPagination, {
          small: false,
          background: true,
          layout: 'total, prev, pager, next',
          ...pagination.value,
          ...props.paginationEvents
        })
      )
    }
    return {
      createTable,
      createPagination
    }
  },

第三步:使用render渲染表格和分页的函数

render() {
    return h('div', {}, [this.createTable(), this.createPagination()])
  }

第二步:如何使用

第一步:引入该文件并且注册,比如:

import PaginationTable from '@/components/PaginationTable.js'
components: {
    PaginationTable
  },

第二步:定义表格和分页需要的数据

如何定义columns呢?下面列举一个
PS:columns中定义的prop的值记得和tableData中的键对应上哦,如果在某条件下需要隐藏该行,可以加上hide:true即可

       {
           type: 'selection'
        },
        {
          label: 'ID',
          prop: 'id',
          hide:true,
          'show-overflow-tooltip': true,
          width: '100px'
        },
        {
          label: '名称',
          'show-overflow-tooltip': true,
          render: {
            default: (scope) => {
              if (props.id === 1) {
                return (<a onClick={() => handleEdit(scope.row)}>{scope.row.name}</a>)
              } else {
                return (<span>{scope.row.name}</span>)
              }
            }
          }
        },

对应的tableData:

[{id:1,name:'juejin1'},{id:2,name:'juejin2'}]

如何定义pagination呢?例子请看下面

const pagination ={
        pageSize: 10,
        pageNo: 1,
        total: 0
      }

第三步:使用组件

handleSelectionChange:选择框的事件
onCurrentChange:分页的翻页事件

<PaginationTable
      ref="paginationTable"
      :table-data="tableData"
      :columns="columns"
      :pagination="pagination"
      :table-events="{
        onSelectionChange: handleSelectionChange
      }"
      :pagination-events="{
        onCurrentChange: handlePageChange
      }"
    />

last but not the least,如果在columns中想要使用自定义的jsx语法的render,使用的时候记得加上 lang="jsx"哦

<script lang="jsx">