项目用的都是antd组件,这里的userList组件展示的表单组件的数据直接get请求拿过来展示的,这里随机生成了50个用户只是为了展示表单的api设置。首先就是表单展示需要两个参数current和pageSize两个属性控制表单的最大分页和当前页面。那么我们就设置初始值然后通过访问服务器返回来一些数据,这里我们不用服务器返回的,只是用自己设置的一些数据去展示效果,还有onChange自带的api监听page和pageSize去获取变化后的然后更新就好了,.直接上代码。
1.userList动态展示
效果图
编辑
typescript
import React, { useState, useEffect, useRef } from 'react'
import type { PageParams, User } from '@/types/api'
import type { TableColumnsType } from 'antd'
import { Button, Table, Form, Input, Select, Space } from 'antd'
import api from '@/api/index'
import { toLocalDate } from '@/utils'
import CreateUser from './CreateUser'
import type { IAction } from '@/types/modal'
export default function UserList() {
const userRef = useRef<{
open: (type: IAction, data?: User.UserItem) => void | undefined
}>(null)
//获取表单对象 用里面的方法 getFieldsValue获取表单中填写的内容
const [form] = Form.useForm()
const [data, setData] = useState<User.UserItem[]>([])
const [total, setTotal] = useState(0)
const [pagination, setPagination] = useState({
current: 1,
pageSize: 10
})
// 获取用户列表
const getUserList = async (params: PageParams) => {
const values = form.getFieldsValue()
const data = await api.getUserList({
...values,
pageNum: params.pageNum,
pageSize: params.pageSize
})
const list = Array.from({ length: 51 })
.fill({})
.map((item: any) => {
item = { ...data.list[0] }
item.userId = Math.random()
return item
})
setData(list) // 注意:接口返回结构要和这里匹配
setTotal(list.length)
setPagination({
current: params.pageNum,
pageSize: params.pageSize
})
}
//创建
const handleCreate = () => {
userRef.current?.open('create')
}
//搜索
const handleSearch = () => {
getUserList({
pageNum: 1,
pageSize: pagination.pageSize
})
}
//重置 表单
const handleReset = () => {
form.resetFields()
}
// 组件挂载时调用
useEffect(() => {
getUserList({
pageNum: pagination.current,
pageSize: pagination.pageSize
})
}, [pagination.current, pagination.pageSize])
const columns: TableColumnsType<User.UserItem> = [
{
title: '用户ID',
dataIndex: 'userId',
key: 'userId'
},
{
title: '用户名称',
dataIndex: 'userName',
key: 'userName'
},
{
title: '用户邮箱',
dataIndex: 'userEmail',
key: 'userEmail'
},
{
title: '用户角色',
dataIndex: 'role',
key: 'role',
render(role: number) {
return {
0: '超级管理员',
1: '管理员',
2: '体验管理员',
3: '普通用户'
}[role]
}
},
{
title: '用户状态',
dataIndex: 'state',
key: 'state',
render(state: number) {
return {
1: '在职',
2: '离职',
3: '试用期'
}[state]
}
},
{
title: '注册时间',
dataIndex: 'create', // 你的字段是 create,不是 createTime
key: 'create',
render(createTime: string) {
return toLocalDate(createTime)
}
},
{
title: '操作',
key: 'action',
render(_, record) {
return (
<Space>
<Button type='text'>编辑</Button>
<Button type='text' danger>
删除
</Button>
</Space>
)
}
}
]
return (
<div className='user-list'>
<Form
form={form}
className='search-form'
layout='inline'
initialValues={{ state: 0 }}
>
<Form.Item name='userId' label='用户ID'>
<Input placeholder='请输入用户ID' />
</Form.Item>
<Form.Item name='userName' label='用户名称'>
<Input placeholder='请输入用户名称' />
</Form.Item>
<Form.Item name='state' label='状态'>
<Select style={{ width: 120 }}>
<Select.Option value={0}>所有</Select.Option>
<Select.Option value={1}>在职</Select.Option>
<Select.Option value={2}>试用</Select.Option>
<Select.Option value={3}>离职</Select.Option>
</Select>
</Form.Item>
<Form.Item>
<Space>
<Button onClick={handleSearch} type='primary' className='mr10'>
搜索
</Button>
<Button onClick={handleReset} type='default'>
重置
</Button>
</Space>
</Form.Item>
</Form>
<div className='base-table'>
<div className='header-wrapper'>
<div className='title'>用户列表</div>
<div className='action'>
<Button type='primary' onClick={handleCreate}>
新增
</Button>
<Button type='primary' danger>
批量删除
</Button>
</div>
</div>
<Table
rowKey='userId' // 保证每行有唯一 key
pagination={{
position: ['bottomRight'],
current: pagination.current,
pageSize: pagination.pageSize,
total: total,
showQuickJumper: true,
showSizeChanger: true,
showTotal: function (total) {
return 总共:${total}条
},
onChange: (page, pageSize) => {
setPagination({
current: page,
pageSize: pageSize
})
}
}}
bordered
rowSelection={{ type: 'checkbox' }}
dataSource={data}
columns={columns}
/>
</div>
<CreateUser
mRef={userRef}
updata={() => {
getUserList({
pageNum: 1,
pageSize: 10
})
}}
/>
</div>
)
}
2.创建表单以及上传头像功能(点击新增弹出取消关闭以及发送成功关闭)
效果图
编辑
静态的展示就不说了,用户头像我们在上传之前,
编辑
无非就是上传之后服务器发送回来url然后去替换展示,然后三元表达式就实现了。主要是怎么可以实现点击新增跳出来子组件也就是创建表单。
首先我们可以设置子组件默认不展示的,也就是open我们设置为关闭,我们希望父组件可以操作子组件的属性,而且我们还希望添加成功后立马重新加载获取新列表,那么我们就给子组件传递参数,一个我们设置的ref扔过去,以及一个更新方法。
然后子组件mRef绑定父组件设置的ref那么就拿到了子组件的DOM元素了,但是方法还是拿不到,也就是我们没办法去操作子组件设置的vibale状态去控制子组件的展示和关闭,那么子组件用useImperativehandle暴露一个open方法,然后open方法可以接收一个类型,因为这个表单我们要在增加更新都需要用到,然后更新vision,这样就实现了完整了逻辑。上代码。
typescript
import React, { useState, useEffect, useRef } from 'react'
import type { PageParams, User } from '@/types/api'
import type { TableColumnsType } from 'antd'
import { Button, Table, Form, Input, Select, Space } from 'antd'
import api from '@/api/index'
import { toLocalDate } from '@/utils'
import CreateUser from './CreateUser'
import type { IAction } from '@/types/modal'
export default function UserList() {
const userRef = useRef<{
open: (type: IAction, data?: User.UserItem) => void | undefined
}>(null)
//获取表单对象 用里面的方法 getFieldsValue获取表单中填写的内容
const [form] = Form.useForm()
const [data, setData] = useState<User.UserItem[]>([])
const [total, setTotal] = useState(0)
const [pagination, setPagination] = useState({
current: 1,
pageSize: 10
})
// 获取用户列表
const getUserList = async (params: PageParams) => {
const values = form.getFieldsValue()
const data = await api.getUserList({
...values,
pageNum: params.pageNum,
pageSize: params.pageSize
})
const list = Array.from({ length: 51 })
.fill({})
.map((item: any) => {
item = { ...data.list[0] }
item.userId = Math.random()
return item
})
setData(list) // 注意:接口返回结构要和这里匹配
setTotal(list.length)
setPagination({
current: params.pageNum,
pageSize: params.pageSize
})
}
//创建
const handleCreate = () => {
userRef.current?.open('create')
}
//搜索
const handleSearch = () => {
getUserList({
pageNum: 1,
pageSize: pagination.pageSize
})
}
//重置 表单
const handleReset = () => {
form.resetFields()
}
// 组件挂载时调用
useEffect(() => {
getUserList({
pageNum: pagination.current,
pageSize: pagination.pageSize
})
}, [pagination.current, pagination.pageSize])
const columns: TableColumnsType<User.UserItem> = [
{
title: '用户ID',
dataIndex: 'userId',
key: 'userId'
},
{
title: '用户名称',
dataIndex: 'userName',
key: 'userName'
},
{
title: '用户邮箱',
dataIndex: 'userEmail',
key: 'userEmail'
},
{
title: '用户角色',
dataIndex: 'role',
key: 'role',
render(role: number) {
return {
0: '超级管理员',
1: '管理员',
2: '体验管理员',
3: '普通用户'
}[role]
}
},
{
title: '用户状态',
dataIndex: 'state',
key: 'state',
render(state: number) {
return {
1: '在职',
2: '离职',
3: '试用期'
}[state]
}
},
{
title: '注册时间',
dataIndex: 'create', // 你的字段是 create,不是 createTime
key: 'create',
render(createTime: string) {
return toLocalDate(createTime)
}
},
{
title: '操作',
key: 'action',
render(_, record) {
return (
<Space>
<Button type='text'>编辑</Button>
<Button type='text' danger>
删除
</Button>
</Space>
)
}
}
]
return (
<div className='user-list'>
<Form
form={form}
className='search-form'
layout='inline'
initialValues={{ state: 0 }}
>
<Form.Item name='userId' label='用户ID'>
<Input placeholder='请输入用户ID' />
</Form.Item>
<Form.Item name='userName' label='用户名称'>
<Input placeholder='请输入用户名称' />
</Form.Item>
<Form.Item name='state' label='状态'>
<Select style={{ width: 120 }}>
<Select.Option value={0}>所有</Select.Option>
<Select.Option value={1}>在职</Select.Option>
<Select.Option value={2}>试用</Select.Option>
<Select.Option value={3}>离职</Select.Option>
</Select>
</Form.Item>
<Form.Item>
<Space>
<Button onClick={handleSearch} type='primary' className='mr10'>
搜索
</Button>
<Button onClick={handleReset} type='default'>
重置
</Button>
</Space>
</Form.Item>
</Form>
<div className='base-table'>
<div className='header-wrapper'>
<div className='title'>用户列表</div>
<div className='action'>
<Button type='primary' onClick={handleCreate}>
新增
</Button>
<Button type='primary' danger>
批量删除
</Button>
</div>
</div>
<Table
rowKey='userId' // 保证每行有唯一 key
pagination={{
position: ['bottomRight'],
current: pagination.current,
pageSize: pagination.pageSize,
total: total,
showQuickJumper: true,
showSizeChanger: true,
showTotal: function (total) {
return 总共:${total}条
},
onChange: (page, pageSize) => {
setPagination({
current: page,
pageSize: pageSize
})
}
}}
bordered
rowSelection={{ type: 'checkbox' }}
dataSource={data}
columns={columns}
/>
</div>
<CreateUser
mRef={userRef}
updata={() => {
getUserList({
pageNum: 1,
pageSize: 10
})
}}
/>
</div>
)
}