@uiw-admin/components
Version:
820 lines (738 loc) • 22.3 kB
Markdown
## ProTable
集成搜索表单的Table组件,用于一般页面的查询搜索。解决业务中**查询条件+Table**的样板代码问题。 **依赖于uiw v4.10.7以上版本**
## 何时使用
当你的表格需要与服务端进行交互,又或者表格有查询条件时使用
### 基础用例
```jsx mdx:preview
import React from 'react';
import { ProTable, useTable } from '@uiw-admin/components';
import { Icon } from 'uiw';
function Demo1() {
const table = useTable('https://randomuser.me/api', {
// 格式化接口返回的数据,必须返回{total 总数, data: 列表数据}的格式
formatData: (data) => {
return {
total: 100,
data: data.results,
};
},
// 格式化查询参数 会接收到pageIndex 当前页 searchValues 表单数据
query: (pageIndex, pageSize, searchValues) => {
return {
page: pageIndex,
results: pageSize,
...searchValues,
}
},
requestOptions: {method: 'GET'}
});
return (
<ProTable
// 搜索栏按钮
bordered
searchBtns={[
{
label: '搜索',
type: 'primary',
onClick: () => {
table.onSearch()
},
},
{
label: '重置',
onClick: () => {
table.onReset()
},
},
]}
paginationProps={{
pageSizeOptions: [10,20,30],
pageSize: 10,
}}
table={table}
columns={[
{
title: '名字',
key: 'name',
props: {
widget: 'input',
initialValue: '',
widgetProps: {
placeholder: '输入用户名',
},
},
render: (text) => {
return <div>{text.title}.{text.first}{text.last}</div>
}
},
{
title: '年龄',
key: 'registered',
props: {
widget: 'select',
key: 'age',
option: [
{ label: '20', value: 20 },
{ label: '10', value: 10 },
],
},
render: (text) => {
return <div>{text.age}</div>
}
},
{
title: '手机号',
key: 'phone',
},
{
title: '性别',
key: 'gender',
props: {
widget: 'select',
option: [
{ label: 'female', value: 'female' },
{ label: 'male', value: 'male' },
],
},
},
]}
/>
);
}
export default Demo1
```
### 显示操作栏
> 操作栏区域默认是`Button`按钮,可通过`render`自定义
<!--rehype:bgwhite=true&codesandbox=true&codepen=true-->
```jsx mdx:preview
import React from 'react';
import { ProTable, useTable } from '@uiw-admin/components';
import { Dropdown, Menu, ButtonGroup, Button, Divider, Icon } from 'uiw';
const menu = (
<div>
<Menu bordered style={{ minWidth: 120 }}>
<Menu.Item icon="reload" text="重新加载" />
<Menu.Item icon="heart-on" text="另存为" active />
<Menu.Item icon="appstore" text="应用商城" />
<Menu.Item icon="bar-chart" text="月统计报表" />
<Menu.Item icon="setting" text="偏好设置" />
</Menu>
</div>
);
function Demo2() {
const table = useTable('https://randomuser.me/api', {
formatData: (data) => {
return {
total: 100,
data: data.results,
};
},
query: (pageIndex, pageSize, searchValues) => {
return {
page: pageIndex,
results: pageSize,
pageSize: 10,
...searchValues,
}
},
requestOptions: {method: 'GET'}
});
return (
<ProTable
// 操作栏按钮
operateButtons={[
{ label: '自定义查询', type: 'primary', style: {marginRight: 10} },
{
render: <Dropdown trigger="click" menu={menu} >
<a href='#' onClick={e => e.preventDefault()}>
点击我出现下拉菜单 <Icon type="down" />
</a>
</Dropdown>
},
]}
table={table}
columns={[
{
title: '名字',
key: 'name',
props: {
widget: 'input',
initialValue: '',
widgetProps: {
preIcon: 'tag',
placeholder: '输入用户名',
},
},
render: (text) => {
return <div>{text.title}.{text.first}{text.last}</div>
}
},
{
title: '年龄',
key: 'registered',
props: {
widget: 'select',
key: 'age',
option: [
{ label: '20', value: 20 },
{ label: '10', value: 10 },
],
},
render: (text) => {
return <div>{text.age}</div>
}
},
{
title: '手机号',
key: 'phone',
},
{
title: '性别',
key: 'gender',
props: {
widget: 'select',
option: [
{ label: 'female', value: 'female' },
{ label: 'male', value: 'male' },
],
},
},
]}
/>
);
}
export default Demo2
```
### table多选、单选行
<!--rehype:bgwhite=true&codesandbox=true&codepen=true-->
```jsx mdx:preview
import React, { useState } from 'react';
import { ProTable, useTable } from '@uiw-admin/components';
function Demo3() {
const [isSingle, SetInSingle] = useState(false)
const table = useTable('https://randomuser.me/api', {
formatData: (data) => {
return {
total: 10,
data: data.results,
};
},
query: (pageIndex, pageSize, searchValues) => {
return {
page: pageIndex,
results: pageSize,
pageSize: 10,
...searchValues,
}
},
requestOptions: {method: 'GET'}
});
return (
<>
<div style={{whiteSpace: 'break-spaces'}}>选中的值{JSON.stringify(table && table.selection.selected)}</div>
<ProTable
// 操作栏按钮
operateButtons={[
{ label: '全选', type: 'primary', onClick: () => { table.selection.selectAll() } },
{ label: '取消全选', type: 'primary', onClick: () => { table.selection.unSelectAll() } },
{ label: '切换', type: 'primary', onClick: () => { table.selection.toggleAll() } },
{ label: '单选多选切换', type: 'primary', onClick: () => {
table.selection.unSelectAll()
SetInSingle(!isSingle)
}},
]}
table={table}
rowSelection={{
// 多选 checkbox 单选radio
type: isSingle ? 'radio' : 'checkbox',
// 选中的键名 column里的key
selectKey: 'name',
// 默认值
defaultSelected: [],
}}
// 取消全部选择
onPageChange={() => {
table.selection.unSelectAll()
}}
columns={[
{
title: '名字',
key: 'name',
props: {
widget: 'input',
initialValue: '',
widgetProps: {
preIcon: 'tag',
placeholder: '输入用户名',
},
},
render: (text) => {
return <div>{text.title}.{text.first}{text.last}</div>
}
},
]}
/>
</>
);
}
export default Demo3
```
### table表单验证
<!--rehype:bgwhite=true&codesandbox=true&codepen=true-->
```jsx mdx:preview
import React from 'react';
import { ProTable, useTable } from '@uiw-admin/components';
function Demo4() {
const table = useTable('https://randomuser.me/api', {
// 格式化接口返回的数据,必须返回{total 总数, data: 列表数据}的格式
formatData: (data) => {
return {
total: 100,
data: data.results,
};
},
// 格式化查询参数 会接收到pageIndex 当前页 searchValues 表单数据
query: (pageIndex, pageSize, searchValues) => {
return {
page: pageIndex,
results: pageSize,
...searchValues,
}
},
requestOptions: {method: 'GET'}
});
return (
<ProTable
// 搜索栏按钮
searchBtns={[
{
label: '搜索',
type: 'primary',
onClick: () => {
table.onSearch()
},
},
{
label: '重置',
onClick: () => {
table.onReset()
},
},
]}
onBeforeSearch={({ initial, current }) => {
const errorObj = {};
if (!current.name) errorObj.name = '名字不能为空!';
if (!current.age) errorObj.age = '年龄不能为空!';
if (!current.gender) errorObj.gender = '性别不能为空!';
if (Object.keys(errorObj).length > 0) {
const err = new Error();
err.filed = errorObj;
throw err;
}
return true;
}}
paginationProps={{
pageSizeOptions: [10,20,30],
pageSize: 10,
}}
table={table}
columns={[
{
title: '名字',
key: 'name',
props: {
widget: 'input',
initialValue: '',
widgetProps: {
preIcon: 'tag',
placeholder: '输入用户名',
},
},
render: (text) => {
return <div>{text.title}.{text.first}{text.last}</div>
}
},
{
title: '年龄',
key: 'registered',
props: {
widget: 'select',
key: 'age',
option: [
{ label: '20', value: 20 },
{ label: '10', value: 10 },
],
},
render: (text) => {
return <div>{text.age}</div>
}
},
{
title: '手机号',
key: 'phone',
},
{
title: '性别',
key: 'gender',
props: {
widget: 'select',
option: [
{ label: 'female', value: 'female' },
{ label: 'male', value: 'male' },
],
},
},
]}
/>
);
}
export default Demo4
```
### 表头分组
与uiw table使用方法一致,可通过传props配置统一的表单
<!--rehype:bgwhite=true&codesandbox=true&codepen=true-->
```jsx mdx:preview
import React from 'react';
import { ProTable, useTable } from '@uiw-admin/components';
function Demo5() {
const table = useTable('https://randomuser.me/api', {
// 格式化接口返回的数据,必须返回{total 总数, data: 列表数据}的格式
formatData: (data) => {
data.results = data.results.map(res => ({
...res,
city: res.location.city,
country: res.location.country,
}))
return {
total: 100,
data: data.results,
};
},
// 格式化查询参数 会接收到pageIndex 当前页 searchValues 表单数据
query: (pageIndex, pageSize, searchValues) => {
return {
page: pageIndex,
results: pageSize,
...searchValues,
}
},
requestOptions: {method: 'GET'}
});
return (
<ProTable
// 搜索栏按钮
searchBtns={[
{
label: '搜索',
type: 'primary',
onClick: () => {
table.onSearch()
},
},
{
label: '重置',
onClick: () => {
table.onReset()
},
},
]}
paginationProps={{
pageSizeOptions: [10,20,30],
pageSize: 10,
}}
table={table}
columns={[
{
title: '名字',
key: 'name',
width: 100,
props: {
widget: 'input',
initialValue: '',
widgetProps: {
preIcon: 'tag',
placeholder: '输入用户名',
},
},
render: (text) => {
return <div>{text.title}.{text.first}{text.last}</div>
}
},
{
title: '年龄',
key: 'registered',
width: 100,
props: {
widget: 'select',
key: 'age',
option: [
{ label: '20', value: 20 },
{ label: '10', value: 10 },
],
},
render: (text) => {
return <div>{text.age}</div>
}
},
{
title: '区域',
key: 'location',
children: [{
title: '城市',
key: 'city',
props: {
widget: 'input',
initialValue: '',
widgetProps: {
placeholder: '输入国家',
},
},
}, {
title: '国家',
key: 'country',
}]
}
]}
/>
);
}
export default Demo5
```
### 自定义表单列
默认是一行五个,可自定义
<!--rehype:bgwhite=true&codesandbox=true&codepen=true-->
```jsx mdx:preview
import React from 'react';
import { ProTable, useTable } from '@uiw-admin/components';
function Demo6() {
const table = useTable('https://randomuser.me/api', {
// 格式化接口返回的数据,必须返回{total 总数, data: 列表数据}的格式
formatData: (data) => {
return {
total: 100,
data: data.results,
};
},
// 格式化查询参数 会接收到pageIndex 当前页 searchValues 表单数据
query: (pageIndex, pageSize, searchValues) => {
return {
page: pageIndex,
results: pageSize,
...searchValues,
}
},
requestOptions: {method: 'GET'}
});
return (
<ProTable
formCol={2}
// 搜索栏按钮
searchBtns={[
{
label: '搜索',
type: 'primary',
onClick: () => {
table.onSearch()
},
},
{
label: '重置',
onClick: () => {
table.onReset()
},
},
]}
paginationProps={{
pageSizeOptions: [10,20,30],
pageSize: 10,
}}
table={table}
columns={[
{
title: '名字',
key: 'name',
props: {
widget: 'input',
initialValue: '',
widgetProps: {
preIcon: 'tag',
placeholder: '输入用户名',
},
},
render: (text) => {
return <div>{text.title}.{text.first}{text.last}</div>
}
},
{
title: '年龄',
key: 'registered',
props: {
widget: 'select',
key: 'age',
option: [
{ label: '20', value: 20 },
{ label: '10', value: 10 },
],
},
render: (text) => {
return <div>{text.age}</div>
}
},
{
title: '手机号',
key: 'phone',
},
{
title: '性别',
key: 'gender',
props: {
widget: 'select',
option: [
{ label: 'female', value: 'female' },
{ label: 'male', value: 'male' },
],
},
},
]}
/>
);
}
export default Demo6
```
## Props
| 参数 | 说明 | 类型 | 默认值 |
| ---- | ---- | ---- | ---- |
| columns | 与`uiw table` columns用法一致 必传, 如果需要表单,也在此增加`props` | `FormCol[]` | [] |
| operateButtons | 操作栏按钮集合,属性与uiw button一致并支持自定义render | `Array<ButtonProps & { render?: JSX.Element }>` | [] |
| searchBtns | 搜索栏按钮集合,属性与uiw button一致并支持自定义render | `Array<ButtonProps & { render?: JSX.Element }>` | [] |
| table | 必传。useTable返回值 | `object` | - |
| onPageChange | 分页回调 | `(page: number) => void` | - |
| onBeforeSearch | 查询table前表单回调,可用于表单验证,返回true 继续查询 | `({initial, current}) => Boolean` | - |
| rowSelection | 选择框配置 | `RowSelection` | - |
| scroll | 设置横向滚动 | `ScrollProps` | - |
| paginationProps| 分页属性 | 继承自[uiw Pagination](https://uiwjs.github.io/#/components/pagination) | - |
| formCol | 网格中表单一行列数 | `number` | `5`|
| tableBackgroundColor | 网格中表格的背景色 | `React.CSSProperties['backgroundColor']` | - |
| tableHeadHidden | 网格中表头是否显示 | `boolean` | `false` |
更多属性文档请参考 [uiw/Table](https://uiwjs.github.io/#/components/table)
### searchBtns
| 参数 | 说明 | 类型 | 默认值 |
| --------------- | ---------------------------------------- | -------- | ------ |
| label | 按钮标题 | `string` | - |
| render | 不使用button,自定义组件 | `React Component` | - |
更多属性文档请参考 [uiw button](https://uiwjs.github.io/#/components/button)
### operateButtons
与`searchBtns`参数一致
### rowSelection
| 参数 | 说明 | 类型 | 默认值 |
| --------------- | ---------------------------------------- | -------- | ------ |
| checkbox | 选择框类型 | `checkbox \| radio` | `checkbox` |
| selectKey | 选择框的键名,必填,对应的column里的key。 | `string` | - |
| defaultSelected | 选中默认值 | `string[]` | - |
### ScrollProps
| 参数 | 说明 | 类型 | 默认值 |
| ---- | ------- | ---------------- | ------ |
| x | x轴宽度 | string 或 number | - |
其余属性与uiw Table一致
### columns props
配置搜索表单
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| widget | 表单组件 | 支持例子中的组件, 组件名与uiw表单组件名字一致,只是首字母小写了 | - |
| widgetProps | 组件属性 | 与uiw对应的组件属性一致 | - |
| label | 表单标题,如果不填则继承columns title | `string` | - |
| key | 表单name,如果不填则继承columns key | `string` | - |
| option | 组件 是`checkbox`、`select`、`searchSelect`、`searchTree` 使用, 数据源统一叫option | `array` | - |
当前支持的widget组件有
```
input
radio,
checkbox,
switch,
select,
searchSelect,
textarea,
dateInput,
timePicker,
monthPicker
searchTree,
dateInputRange
```
props可以是个对象属性值是以上参数,也可以是个数组方便处理筛选条件大于列表展示的情况
```js
// 对象
props: {
widget: 'input',
initialValue: 'zzz',
widgetProps: {
preIcon: 'tag',
placeholder: '输入用户名',
}
}
// 数组
props: [
{
widget: 'input',
initialValue: 'zzz',
key: 'name'
},
{
widget: 'input',
initialValue: 'a',
},
],
```
### paginationProps
| 参数 | 说明 | 类型 | 默认值 |
| ------- | ------------ | ------ | ------ |
| pageSizeOptions | 指定每页可以显示多少条 | `number[]` | - |
| pageSize | 每页条数 | `number` | `10` |
| onShowSizeChange | pageSize 变化的回调 | `(current, pageSize) => void` | - |
更多属性文档请参考 [uiw Pagination](https://uiwjs.github.io/#/components/pagination)
## useTable
### params
| 参数 | 说明 | 类型 | 默认值 |
| ------- | ------------ | ------ | ------ |
| api | 接口请求地址 | `string` | - |
| options | 配置集合 | `object` | {} |
### options
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| formatData | 格式化接口返回的数据,必须返回{total: 总数, data: 列表数据}的格式 | (data) => {total: 10, data: []} | - |
| mutationOptions | [useReactMutation](https://uiwjs.github.io/uiw-admin/#/docs/request)配置 | ReactMutationOptions | - |
| query | 格式化请求参数, 会接收到pageIndex 当前页 searchValues 表单数据 | (pageIndex: number, searchValues: any) => {page: pageIndex, pageSize: 10, searchValues} | {} |
| requestOptions | request参数,继承自`fetch` | object | {} |
### response
| 参数 | 说明 | 类型 | 默认值 |
| ------------ | ------------ | ------------- | ------ |
| data | 接口请求数据 | `any[]` | - |
| total | 数据总数 | `number` | - |
| searchValues | 表单值 | `object` | - |
| selection | 选择框属性 | `UseSelections` | - |
| pageIndex | 当前分页 | `number` | `1` |
| onRefersh | 刷新分页数据 | `() => void` | - |
| onReset | 重置表单,查询数据 | `() => void` | - |
| onSearch | 查询数据 | `() => void` | - |
| form | 返回搜索表单form实例各种内部函数,可用于主动触发事件, 与[Uiw Form](https://uiwjs.github.io/#/components/form) ref 属性返回的一致 | `Ref` | - |
### selection
| 参数 | 说明 | 类型 | 默认值 |
| ----------------- | ------------------ | --------------------- | ------ |
| selected | 已经选择的元素 | `array` | - |
| allSelected | 是否全选 | `boolean` | - |
| noneSelected | 是否一个都没有选择 | `boolean` | - |
| partiallySelected | 是否半选 | boolean | - |
| isSelected | 是否被选择 | `(value: T) => boolean` | - |
| setSelected | 设置选择的元素 | `(value: T[]) => void` | - |
| select | 选择元素 | `(value: T) => void ` | - |
| unSelect | 取消选择元素 | `(value: T) => void` | - |
| toggle | 反选元素 | `(value: T) => void` | - |
| selectAll | 选择全部元素 | `() => void` | - |
| unSelectAll | 取消选择全部元素 | `() => void` | - |
| toggleAll | 反选全部元素 | `() => void` | - |
## 贡献者
感谢所有的贡献者,欢迎开发者为开源项目贡献力量。
<a href="https://github.com/uiwjs/uiw-admin/graphs/contributors">
<img src="https://uiwjs.github.io/uiw-admin/CONTRIBUTORS.svg" />
</a>
## License
Licensed under the MIT License.