这段时间做react项目遇到一些平常并不会去在意的问题,但解决的时候又需要思考一番。这次开发用到了蚂蚁金服的UI框架Ant Design。项目中有一个模块的样式和功能用到了折叠面板Collapse组件来实现。但是开发完成后有一个问题被产品提到了。
问题是这样的,因为我们有一个公告展示的列表,是分页展示的,当用户在第某一页面打开一个或多个面板并且没有关闭就去点击其他的页码,当他再次返回到当前页面时折叠面板仍然是展开的。产品的要求是当用户在某一页打开折叠面板,从别的页面再次回来的时候要求折叠面板都关闭。我感觉这个并不影响什么,既然产品提出来了我们就要着手解决他。
翻看了官方文档提供的API动手实践了一下发现可以通过activeKey(数字数组/字符串数组)属性和事件onChange来实现。接下来我们来看看实现的方法(可能还有很多更好的方法,我目前只想到了这一种,有更好实现的大佬希望可以指教,感谢!)。在这个项目中用的react的新特性hooks,而且由于消息分类页面有好几个所以是把Collapse抽离出来一个组件,所以涉及到了组件之间的传值。
抽离的Collapse(子组件)组件:
import React, { useState } from "react";
import { Collapse } from "antd";
import Templatelist from "components/notice/listDom";//这个是面板header内容根据自己项目来定
interface props {//项目用到了ts
dataList: any;//父组件传过来的消息数据
changeKeys: Function;//父组件传过来的方法
keys?: Boolean;//父组件传过来的一个boolean类型的值,用它来控制面板是否折叠,注意:true表示折叠,false表示展开
}
export default function noticeCollapse({ dataList, changeKeys, keys }: props) {
const { Panel } = Collapse;
let [key, setKey] = useState([]);//声明了一个状态key用来存储展开的面板
function handleKeyChange(e) {//实现Collapse自带的onChange方法
changeKeys(false);//触发面板的onChange时设置父组件的show为false,即此时activeKey的值为key
setKey(e);存储当前点开的面板值到key中
}
return (
<Collapse
expandIconPosition="right"
activeKey={keys ? [] : key}//如果keys为true设置面板展开数量为空,即都折叠
onChange={handleKeyChange}
>
{dataList && dataList.length > 0
? dataList.map(item => (
<Panel
header={<Templatelist objs={item}></Templatelist>}
key={item.messageId}
>
<div
className="contentW"
dangerouslySetInnerHTML={{ __html: item.content }}
></div>
</Panel>
))
: ""}
</Collapse>
);
}
引用Collapse的组件(父组件)
import React, { useEffect, useState } from "react";
import Layout from "components/layout";//项目公共布局组件
import { Noticelist, PaginationBox } from "components/ui/notice";//公共样式组件
import { Pagination } from "antd";//antd分页组件
import MangeVoid from "components/manage/manage-void";//若消息为空展示的空页面组件
import { getMgMsg } from "api/notice";//获取数据的方法
import NoticeCollapse from "components/notice/collapse";//引入抽离的Collapse组件
function NoticeBaseInfo() {
let [show, setShow] = useState(false);//控制面板的折叠隐藏,需要传给抽离的Collapse组件
const [allMsg, setmgMsg] = useState({//存放消息数据
total: 0,
list: [],
pageSize: 10,
pageNum: 1
});
let [isvoid, setVoid] = useState(false);//这个作用是为了在异步加载数据时防止空页面闪一下
let initMsg = pageNum => {
getMgMsg("", pageNum, allMsg.pageSize).then(res => {
if (res.msg == "success" && res.data) {
setmgMsg({ ...res.data, pageNum });
if (!isvoid) {
setVoid(true);
}
}
});
};
useEffect(() => {
initMsg(allMsg.pageNum);
}, []);
function handleChange(page) {//分页方法
initMsg(page);
setShow(true);//当点击分页的时候我们设置show为true,即让面板都折叠
}
return (
<Layout>
{isvoid && allMsg.list.length == 0 ? (
<MangeVoid voidText="暂无消息通知"></MangeVoid>
) : (
<Noticelist>
<NoticeCollapse
dataList={allMsg.list}
keys={show}//把show传给子组件
changeKeys={(status) => setShow(status)}//接收子组件传来的值,并赋值给show
></NoticeCollapse>
</Noticelist>
)}
{allMsg.total > 10 ? (
<PaginationBox>
<Pagination
showSizeChanger={false}
current={allMsg.pageNum}
total={allMsg.total}
hideOnSinglePage={true}
onChange={handleChange}
></Pagination>
</PaginationBox>
) : (
""
)}
</Layout>
);
}
export default NoticeBaseInfo;
网友评论