ProTable 数据表格 1.1.0
基于 el-table 进行封装的 JSON 配置化表格,属性、方法完全兼容,用于快速构建表格
基础用法
内置分页组件,使用 hide-pagination 属性控制是否显示分页
显示分页
共 100 条
- 1
- 2
- 3
- 4
- 5
- 6
- 10
页
<template>
<div>
<el-switch
v-model="hidePagination"
active-text="隐藏分页"
inactive-text="显示分页"
style="margin-bottom: 10px"
/>
<pro-table
ref="proTableRef"
border
stripe
height="400px"
:data="data"
:columns="columns"
:total="total"
:hide-pagination="hidePagination"
@pagination-change="handlePagination"
/>
</div>
</template>
<script setup lang="tsx">
import { computed, ref } from 'vue'
import { ProTable } from '@coderhd/pro-element-plus'
import type { ProTableColumn } from '@coderhd/pro-element-plus'
const proTableRef = ref<InstanceType<typeof ProTable>>()
const data = ref<any>(
Array.from({ length: 20 }).map((_, index) => ({
index: index + 1,
name: '姓名',
age: Math.floor(Math.random() * 100),
sex: Math.random() > 0.5 ? '男' : '女',
address: '北京市海淀区',
desc: '很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长的描述',
})),
)
const hidePagination = ref<boolean>(false)
const total = ref<number>(100)
const columns = computed<ProTableColumn[]>(() => [
{
label: '姓名',
prop: 'name',
width: 100,
},
{
label: '年龄',
prop: 'age',
width: 100,
},
{
label: '性别',
prop: 'sex',
width: 100,
},
{
label: '地址',
prop: 'address',
},
{
label: '描述',
prop: 'desc',
showOverflowTooltip: true,
},
{
label: '操作',
prop: 'action',
width: 140,
cellSlots: {
default: (scope) => {
return (
<div>
<el-button
type="primary"
size="small"
// eslint-disable-next-line no-console
onClick={() => console.log(scope)}
>
编辑
</el-button>
<el-button type="danger" size="small">
删除
</el-button>
</div>
)
},
header: () => '自定义',
},
},
])
const handlePagination = (page: number, pageSize: number) => {
// eslint-disable-next-line no-console
console.log({ page, pageSize })
proTableRef.value?.scrollTo({ top: 0, behavior: 'smooth' })
}
</script>
<style scoped></style>查询表格
配合 pro-search-form 组件使用,实现查询表格功能
共 100 条
- 1
- 2
- 3
- 4
- 5
页
<template>
<div v-loading="loading">
<pro-search-form
label-width="80px"
label-suffix=":"
:model="searchForm"
:gutter="20"
:fields="fields"
:auto-search-debounce="300"
@search="handleSearch"
/>
<pro-table
ref="proTableRef"
v-model:current-page="currentPage"
v-model:page-size="pageSize"
border
stripe
height="400px"
:data="data"
:columns="columns"
:total="total"
background
@pagination-change="handlePagination"
/>
</div>
</template>
<script setup lang="tsx">
import { computed, reactive, ref } from 'vue'
import { ProTable } from '@coderhd/pro-element-plus'
import type { ProFormFields, ProTableColumn } from '@coderhd/pro-element-plus'
const proTableRef = ref<InstanceType<typeof ProTable>>()
const searchForm = reactive({})
const currentPage = ref<number>(1)
const pageSize = ref<number>(20)
const data = ref<any>([])
const total = ref<number>(100)
const loading = ref<boolean>(false)
const fields = computed<ProFormFields>(() => [
{
label: '姓名',
prop: 'name',
component: 'ElInput',
componentProps: {
placeholder: '请输入姓名',
},
colProps: {
span: 8,
},
},
{
label: '年龄',
prop: 'age',
component: 'ElInputNumber',
componentProps: {
placeholder: '请输入年龄',
style: { width: '100%' },
},
colProps: {
span: 8,
},
},
{
label: '性别',
prop: 'sex',
component: 'ElSelect',
componentProps: {
placeholder: '请选择性别',
options: [
{ label: '男', value: '1' },
{ label: '女', value: '2' },
],
},
colProps: {
span: 8,
},
},
{
label: '日期',
prop: 'date',
component: 'ElDatePicker',
componentProps: {
placeholder: '请选择日期',
},
colProps: {
span: 8,
},
},
{
label: '状态',
prop: 'status',
component: 'ElSwitch',
componentProps: {
activeValue: true,
inactiveValue: false,
},
colProps: {
span: 8,
},
},
])
const columns = computed<ProTableColumn[]>(() => [
{
label: '序号',
prop: 'index',
width: 100,
},
{
label: '姓名',
prop: 'name',
width: 100,
},
{
label: '年龄',
prop: 'age',
width: 100,
},
{
label: '性别',
prop: 'sex',
width: 100,
},
{
label: '地址',
prop: 'address',
},
{
label: '描述',
prop: 'desc',
showOverflowTooltip: true,
},
{
label: '操作',
prop: 'action',
width: 140,
cellSlots: {
default: (scope) => {
return (
<div>
<el-button
type="primary"
size="small"
// eslint-disable-next-line no-console
onClick={() => console.log(scope)}
>
编辑
</el-button>
<el-button type="danger" size="small">
删除
</el-button>
</div>
)
},
header: () => '自定义',
},
},
])
const handleSearch = () => {
currentPage.value = 1
request()
}
const request = async () => {
loading.value = true
data.value = await new Promise((resolve) => {
setTimeout(() => {
resolve(
Array.from({ length: pageSize.value }).map((_, index) => ({
index: (currentPage.value - 1) * pageSize.value + index + 1,
name: '姓名',
age: Math.floor(Math.random() * 100),
sex: Math.random() > 0.5 ? '男' : '女',
address: '北京市海淀区',
desc: '很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长的描述',
})),
)
}, 1000)
})
loading.value = false
}
const handlePagination = (page: number, pageSize: number) => {
// eslint-disable-next-line no-console
console.log({ page, pageSize })
request()
proTableRef.value?.scrollTo({ top: 0, behavior: 'smooth' })
}
</script>
<style scoped></style>Attributes
更多属性参考 ElementPlus Table Attributes
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| columns | ProTableColumn[] | [] | 列配置 |
| hide-pagination | boolean | false | 是否隐藏分页 |
Events
更多事件参考 ElementPlus Table Events
| 事件名 | 说明 | 回调参数 |
|---|---|---|
| pagination-change | 当分页发生变化时,触发的事件 | (currentPage: number, pageSize: number): void |
Slots
| 插槽名 | 说明 |
|---|---|
| append | 插入至表格最后一行之后的内容, 如果需要对表格的内容进行无限滚动操作,可能需要用到这个 slot。 若表格有合计行,该 slot 会位于合计行之上。 |
| empty | 空数据时显示的内容 |
Exposes
更多实例方法参考ElementPlus Table Methods
类型定义
ts
// import tableProps from 'element-plus/es/components/table/src/table/defaults'
import tableColumnProps from 'element-plus/es/components/table/src/table-column/defaults'
import type { ExtractPublicPropTypes, PropType, VNodeChild } from 'vue'
import type { TableProps, TableColumnCtx, PaginationProps } from 'element-plus'
type DefaultRow = Record<PropertyKey, any>
type CellSlots = {
default?: (data: {
row: any
column: TableColumnCtx<any>
$index: number
}) => VNodeChild
header?: (data: { column: TableColumnCtx<any>; $index: number }) => VNodeChild
filterIcon?: (data: { filterOpened: boolean }) => VNodeChild
expand?: (data: { expanded: boolean }) => VNodeChild
}
export const proTableColumn = {
...tableColumnProps,
/**
* 列插槽
*/
cellSlots: {
type: Object as PropType<CellSlots>,
default: () => ({}),
},
}
export type ProTableColumn = ExtractPublicPropTypes<typeof proTableColumn>
export type ProTableProps<T extends DefaultRow = DefaultRow> = TableProps<T> &
Partial<PaginationProps> & {
/**
* 列配置
*/
columns: ProTableColumn[]
/**
* 是否隐藏分页
* @default false
*/
hidePagination?: boolean
}