Skip to content

ProTable

ProTable 是一个基于 el-tableel-pagination 封装的配置式表格组件,适合在业务中通过 columns 快速描述表格结构。

基础用法

通过 columns 配置列信息,支持 selectionindex、固定列、自定义渲染等常见能力。

<template>
  <ProTable
    :columns="columns"
    :data="data"
    border
    stripe
    hide-pagination
    highlight-current-row
  />
</template>

<script setup lang="tsx">
import type { ProTableColumn } from '@coderhd/pro-element-plus'
import { computed, ref } from 'vue'

type DataRow = {
  name: string
  age: number
  address: string
}

const data = ref<DataRow[]>(
  Array.from({ length: 5 }, (_, i) => ({
    name: `用户 ${i + 1}`,
    age: 20 + i,
    address: `测试地址 ${i + 1}`,
  })),
)

const columns = computed<ProTableColumn<DataRow>[]>(() => [
  {
    type: 'selection',
    width: 60,
  },
  {
    type: 'index',
    label: '序号',
    width: 70,
  },
  {
    label: '姓名',
    prop: 'name',
  },
  {
    label: '年龄',
    prop: 'age',
    width: 100,
  },
  {
    label: '地址',
    prop: 'address',
  },
  {
    label: '操作',
    width: 240,
    fixed: 'right',
    cellSlots: {
      default: () => {
        return (
          <>
            <el-button type="primary" text plain>
              查看
            </el-button>
            <el-button type="success" text plain>
              编辑
            </el-button>
            <el-button type="danger" text plain>
              删除
            </el-button>
          </>
        )
      },
    },
  },
])
</script>

分页用法

组件内置了分页区域,支持:

  • hide-pagination 控制分页显隐
  • v-model:current-pagev-model:page-size 双向绑定
  • total 作为分页总数
  • @pagination 统一抛出页码与每页条数
  • pagination-props 透传其他 el-pagination 属性

暂无数据
共 0 条
  • 1
前往

<template>
  <ProTable
    v-loading="loading"
    v-model:current-page="currentPage"
    v-model:page-size="pageSize"
    :columns="columns"
    :data="data"
    :total="total"
    :pagination-props="paginationProps"
    border
    stripe
    height="320px"
    @pagination="handlePagination"
  />
</template>

<script setup lang="ts">
import type { ProTableColumn } from '@coderhd/pro-element-plus'
import { computed, onMounted, ref } from 'vue'

type DataRow = {
  name: string
  age: number
  address: string
}

const loading = ref(false)
const data = ref<DataRow[]>([])
const total = ref(0)
const currentPage = ref(1)
const pageSize = ref(10)

const columns = computed<ProTableColumn<DataRow>[]>(() => [
  {
    type: 'index',
    label: '序号',
    width: 70,
  },
  {
    label: '姓名',
    prop: 'name',
  },
  {
    label: '年龄',
    prop: 'age',
    width: 100,
  },
  {
    label: '地址',
    prop: 'address',
  },
])

const paginationProps = computed(() => ({
  layout: 'total, sizes, prev, pager, next, jumper',
  pageSizes: [10, 20, 30, 50],
  background: true,
}))

const loadData = async () => {
  try {
    loading.value = true
    await new Promise((resolve) => setTimeout(resolve, 500))
    data.value = Array.from({ length: pageSize.value }, (_, i) => ({
      name: `用户 ${i + 1 + (currentPage.value - 1) * pageSize.value}`,
      age: 20 + (i % 10),
      address: `测试地址 ${i + 1 + (currentPage.value - 1) * pageSize.value}`,
    }))
    total.value = 100
  } finally {
    loading.value = false
  }
}

const handlePagination = (page: number, size: number) => {
  currentPage.value = page
  pageSize.value = size
  loadData()
}

onMounted(() => {
  loadData()
})
</script>

多级表头与插槽

当列配置中存在 children 时,会自动渲染为多级表头。
同时支持两种自定义内容方式:

  • cellSlots:函数式插槽
  • slotNames:模板插槽名称映射

<template>
  <ProTable :columns="columns" :data="data" border stripe hide-pagination>
    <template #custom>
      <span>模板插槽单元格</span>
    </template>

    <template #customHeader>
      <span>模板插槽表头</span>
    </template>
  </ProTable>
</template>

<script setup lang="tsx">
import type { ProTableColumn } from '@coderhd/pro-element-plus'
import { computed, ref } from 'vue'

type DataRow = {
  name: string
  age: number
  address: string
}

const data = ref<DataRow[]>(
  Array.from({ length: 5 }, (_, i) => ({
    name: `用户 ${i + 1}`,
    age: 20 + i,
    address: `测试地址 ${i + 1}`,
  })),
)

const columns = computed<ProTableColumn<DataRow>[]>(() => [
  {
    label: '基础信息',
    align: 'center',
    children: [
      {
        label: '姓名',
        prop: 'name',
        align: 'center',
      },
      {
        label: '年龄',
        prop: 'age',
        align: 'center',
      },
      {
        label: 'JSX 插槽',
        align: 'center',
        cellSlots: {
          default: () => {
            return <el-tag>JSX 单元格</el-tag>
          },
          header: () => {
            return <span>JSX 表头</span>
          },
        },
      },
    ],
  },
  {
    label: '地址信息',
    align: 'center',
    children: [
      {
        label: '地址',
        prop: 'address',
        align: 'center',
      },
      {
        label: '模板插槽',
        align: 'center',
        slotNames: {
          default: 'custom',
          header: 'customHeader',
        },
      },
    ],
  },
])
</script>

API

Props

属性名说明类型默认值
columns表格列配置数组ProTableColumn[][]
hide-pagination是否隐藏分页区域booleanfalse
current-page当前页,支持 v-model:current-pagenumber1
page-size每页条数,支持 v-model:page-sizenumber10
total分页总条数numberdata.length
pagination-props额外透传给 el-pagination 的属性,不包含 currentPagepageSizetotalPaginationProps{ layout: 'total, sizes, prev, pager, next, jumper' }
...el-table props完整支持 el-table 的属性--

ProTableColumn

字段说明类型
label列标题string
prop列字段名string
type列类型,如 selectionindexexpandstring
children子列配置,用于多级表头ProTableColumn[]
hidden是否隐藏当前列,支持静态值或函数boolean | () => boolean
cellSlots函数式插槽配置object
slotNames模板插槽名称映射object
...el-table-column props完整支持 el-table-column 的属性-

Events

事件名说明回调参数
pagination分页变化时统一抛出当前页和每页条数(page: number, pageSize: number) => void
update:currentPage当前页双向绑定事件(page: number) => void
update:pageSize每页条数双向绑定事件(pageSize: number) => void
...el-table events原生 el-table 事件继续可用-

Exposes

ProTable 对外透传了常用的 el-table 实例方法与实例访问能力,包括:

  • clearSelection
  • getSelectionRows
  • toggleRowSelection
  • toggleAllSelection
  • toggleRowExpansion
  • setCurrentRow
  • clearSort
  • clearFilter
  • doLayout
  • sort
  • scrollTo
  • setScrollTop
  • setScrollLeft
  • instance
  • tableRef
  • getInstance