详细介绍:从0开始的中后台管理系统-5(userList动态展示以及上传图片和弹出创建用户表单)
项目用的都是antd组件,这里的userList组件展示的表单组件的数据直接get请求拿过来展示的,这里随机生成了50个用户只是为了展示表单的api设置。首先就是表单展示需要两个参数current和pageSize两个属性控制表单的最大分页和当前页面。那么我们就设置初始值然后通过访问服务器返回来一些数据,这里我们不用服务器返回的,只是用自己设置的一些数据去展示效果,还有onChange自带的api监听page和pageSize去获取变化后的然后更新就好了,.直接上代码。
1.userList动态展示
效果图

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 void | undefined
}>(null)
//获取表单对象 用里面的方法 getFieldsValue获取表单中填写的内容
const [form] = Form.useForm()
const [data, setData] = useState([])
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 = [
{
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 (
编辑
删除
)
}
}
]
return (
所有
在职
试用
离职
搜索
重置
用户列表
新增
批量删除
{
setPagination({
current: page,
pageSize: pageSize
})
}
}}
bordered
rowSelection={{ type: 'checkbox' }}
dataSource={data}
columns={columns}
/>
{
getUserList({
pageNum: 1,
pageSize: 10
})
}}
/>
)
}
2.创建表单以及上传头像功能(点击新增弹出取消关闭以及发送成功关闭)
效果图

静态的展示就不说了,用户头像我们在上传之前,

无非就是上传之后服务器发送回来url然后去替换展示,然后三元表达式就实现了。主要是怎么可以实现点击新增跳出来子组件也就是创建表单。
首先我们可以设置子组件默认不展示的,也就是open我们设置为关闭,我们希望父组件可以操作子组件的属性,而且我们还希望添加成功后立马重新加载获取新列表,那么我们就给子组件传递参数,一个我们设置的ref扔过去,以及一个更新方法。
然后子组件mRef绑定父组件设置的ref那么就拿到了子组件的DOM元素了,但是方法还是拿不到,也就是我们没办法去操作子组件设置的vibale状态去控制子组件的展示和关闭,那么子组件用useImperativehandle暴露一个open方法,然后open方法可以接收一个类型,因为这个表单我们要在增加更新都需要用到,然后更新vision,这样就实现了完整了逻辑。上代码。
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 void | undefined
}>(null)
//获取表单对象 用里面的方法 getFieldsValue获取表单中填写的内容
const [form] = Form.useForm()
const [data, setData] = useState([])
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 = [
{
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 (
编辑
删除
)
}
}
]
return (
所有
在职
试用
离职
搜索
重置
用户列表
新增
批量删除
{
setPagination({
current: page,
pageSize: pageSize
})
}
}}
bordered
rowSelection={{ type: 'checkbox' }}
dataSource={data}
columns={columns}
/>
{
getUserList({
pageNum: 1,
pageSize: 10
})
}}
/>
)
}
浙公网安备 33010602011771号