【React入门实践】结合Ant-Design 从0带你手把手开发包含【列表】和【搜索栏】的简单【用户管理

58 阅读3分钟

1. 看页面需求


分析:页面分为两个核心部分:【搜索栏】【列表】

2. 分析接口文档


(1)留言列表接口-主要是在页面初始化时调用。pageNum pageSize为请求参数,非必须。响应参数在list中。

(2)搜索接口 - 但搜索接口一般可以直接使用列表接口即可

  1. 参照UI编写页面代码

(1) 列表部分

使用封装的组件(代码后附),data={listData}表示列表中绑定listData数据,注意dataIndex需要对照接口返回的参数编写

function Feedback({

dispatch,

feedback: { listData, detailData },

loading

}: any) {

const init = useCallback(() => {

dispatch('feedback/init')

}, [dispatch])

useEffect(() => {

init()

}, [init])

const columns = useMemo(

() => [

{

title: '序号',

dataIndex: '_id'

},

{

title: '用户名',

dataIndex: 'username'

},

{

title: '反馈标题',

dataIndex: 'title'

},

{

title: '反馈内容',

dataIndex: 'content',

},

{

title: '提交时间',

dataIndex: 'createdTime',

},

{

title: '状态',

dataIndex: 'status',

},

{

title: '操作',

render: (value: any) => (

<>

{value.status === 0 && (

<a type="primary" onClick={() => toggleMessage(value.id)}>

反馈留言

)}

{value.status === 1 && (

<a type="primary" onClick={() => toggleDetail(value.id)}>

查看

)}

</>

)

}

],

[toggleDetail, toggleMessage]

)

return (

<PageHeaderLayout className={'commonList'}>

<Card

className={styles.table}

style={{ marginTop: 1 }}

bordered={false}

bodyStyle={{ padding: '8px 32px 32px 32px' }}

<StandardTable

loading={loading}

data={listData}

columns={columns}

onChange={handleStandardTableChange}

/>

)

}

(2)search查询栏部分

const Search: any = Form.create()(function({ form, init, dispatch }: any) {

const { validateFields } = form

const simpleForm = useMemo(() => {

const { getFieldDecorator, getFieldValue } = form

const { query } = getLocation()

return (

layout="inline"

style={{ display: 'flex' }}

className={styles.commonForm}

<Form.Item label="">

{getFieldDecorator('username', {

initialValue: query.username

})()}

</Form.Item>

<Form.Item label="">

{getFieldDecorator('title', {

initialValue: query.title

})()}

</Form.Item>

<Form.Item label="">

{getFieldDecorator('submitTimeBegin', {

initialValue: query.startDate || ''

})(

<DatePicker

onChange={change1}

disabledDate={disabledDate1}

placeholder="请选择日期"

/>

)}

</Form.Item>

<Form.Item label="">

{getFieldDecorator('submitTimeEnd', {

initialValue: query.startDate || ''

})(

<DatePicker

onChange={change2}

disabledDate={disabledDate2}

placeholder="请选择日期"

/>

)}

</Form.Item>

<Form.Item>

{getFieldDecorator('status', {

initialValue: query.status || ''

})(

状态 {feedbackStatus.map((v: any) => ( {v.value} ))}

)}

</Form.Item>

查询

<Button

className={styles.reset}

style={{ marginLeft: 10 }}

onClick={handleFormReset}

icon="undo"

重置

)

}, [form, handleFormReset, handleSearch, time1, time2])

return (

{simpleForm}

)

})

可以看到,在页面将search设置成组件,并在后面掉哦组件。至此已达到页面效果,但是还没有数据

4.初始化页面 - 列表数据显示


在page页面的主函数中写init函数

const init = useCallback(() => {

dispatch('feedback/init')

}, [dispatch])

useEffect(() => {

init()

}, [init])

在model页面中写详细的接口调用信息

init: async (action, { dispatch }) => {

const { query } = getLocation()

const data = await dispatch({

type: 'feedback/post',

params: ['manage/feedback/page', { ...query }]

})

dispatch({

type: 'feedback/setStore',

params: [{ listData: listMOM1(data) }]

})

},

其中我们使用到了ListMOM1组件来帮助页面数据回显,其主要功能是,添加页面的数据编号和实现分页功能,详细的封装代码后附。

其中type: 'feedback/setStore',表示把数据存储在缓存中,可以通过组件传递数据,因此在StandardTable中需要绑定data={listData},从而实现数据初始化显示。

// list数据处理中间件

export const listMOM1 = (resData: any) => {

const {

content,

// total,

totalCount,

currPage: currPage = 1,

pageSize: pageSize = 40,

data,

list

} = resData

const list1 = content || data || list

//添加序号

if (list) {

list.forEach((element: any, index: number) => {

element._id = index + 1 + (currPage - 1) * pageSize

element._symbol = element._id

})

}

//分页

const pagination = {

total: totalCount,

pageSize: Number(pageSize) || 40,

current: Number(currPage)

}

return {

list,

pagination: totalCount && { ...listData.pagination, ...pagination }

}

}

5.列表数据按需渲染render


可以看到后台返回的数据如下,

但是,(1)【标题和内容】数据过长,我们需要将其展示前5个字符后省略号(比如这样就。。。).(2)对于【日期】数据只需要显示到具体某天,不需要时分秒,(3)对于【状态】数据显示为0,1但是前端也需要整理为‘未回答’‘已回答’

(1)数据截取缩略显示,hover后显示全部---使用Tooltip组件

{

title: '反馈内容',

dataIndex: 'content',

render: (text: any, record: any, index: any) => {

if (record.content.length <= 5) {

return record.content

} else {

return (

{record.content.substring(0, 5) + '...'}

)

}

}

},

(2)日期截取同理

{

title: '提交时间',

dataIndex: 'createdTime',

render: (text: any, record: any, index: any) => {

return record.createdTime.substring(0, 10)

}

},

(3)对于接口返回的0,1,2状态数值数据需要分情况渲染

{

title: '状态',

dataIndex: 'status',

render: (value: any) => (

<>

{value == 0 && 未回答}

{value == 1 && 已回答}

</>

)

},

最后

资料过多,篇幅有限

自古成功在尝试。不尝试永远都不会成功。勇敢的尝试是成功的一半。

开源分享:docs.qq.com/doc/DSmRnRG…