import React, { useState, useEffect, useRef } from 'react'; import { RouteContext } from '@ant-design/pro-layout'; import { history } from '@umijs/max'; import Tags from './Tags'; import styles from './index.less'; import { Scrollbars } from 'react-custom-scrollbars'; /** * @component TagView 标签页组件 */ const TagView = ({ children, home }) => { const [tagList, setTagList] = useState([]); const [currentPath, setCurrentPath] = useState(); const routeContextRef = useRef(); useEffect(() => { if (routeContextRef.current) { handleOnChange(routeContextRef.current); } }, [routeContextRef.current]); // 初始化 visitedViews,设置首页 const initTags = (routeContext) => { const { menuData } = routeContext; if (tagList.length === 0 && menuData) { const firstTag = menuData.filter((el) => el.path === home)[0]; if (firstTag) { const title = '首页'; const path = firstTag.path; history.push({ pathname: firstTag.path, query: firstTag.query }); setTagList([ { title, path, children: firstTag.element, refresh: 0, active: true, key: firstTag.key, }, ]); } } }; // 监听路由改变 const handleOnChange = (routeContext) => { const { currentMenu } = routeContext; // tags初始化 if (tagList.length === 0) { return initTags(routeContext); } // 判断是否已打开过该页面 let hasOpen = false; if (currentMenu.path) { const tagsCopy = tagList.map((item) => { if (currentMenu?.path === item.path) { //console.log(item); hasOpen = true; // 刷新浏览器时,重新覆盖当前 path 的 children return { ...item, active: true, children: item.children }; } else { return { ...item, active: false }; } }); // 没有该tag时追加一个,并打开这个tag页面 if (!hasOpen) { const title = routeContext.title || ''; const path = currentMenu?.path; tagsCopy.push({ title, path, children, refresh: 0, active: true, }); } return setTagList(tagsCopy); } }; // 关闭标签 const handleCloseTag = (tag) => { const tagsCopy = tagList.map((el, i) => ({ ...el })); // 判断关闭标签是否处于打开状态 tagList.forEach((el, i) => { if (el.path === tag.path && tag.active) { const next = tagList[i - 1]; next.active = true; history.push({ pathname: next?.path, query: next?.query }); } }); setTagList(tagsCopy.filter((el) => el.path !== tag?.path)); }; // 关闭所有标签 const handleCloseAll = () => { const tagsCopy = tagList.filter((el) => el.path === home); history.push(home); setTagList(tagsCopy); }; // 关闭其他标签 const handleCloseOther = (tag) => { const tagsCopy = tagList.filter((el) => el.path === home || el.path === tag.path); history.push({ pathname: tag?.path, query: tag?.query }); setTagList(tagsCopy); }; // 刷新选择的标签 const handleRefreshTag = (tag) => { const tagsCopy = tagList.map((item) => { if (item.path === tag.path) { history.push({ pathname: tag?.path, query: tag?.query }); return { ...item, refresh: item.refresh + 1, active: true }; } return { ...item, active: false }; }); setTagList(tagsCopy); }; return ( <> <RouteContext.Consumer> {(value) => { setTimeout(() => { setCurrentPath(value.currentMenu?.path); }, 0); routeContextRef.current = value; return null; }} </RouteContext.Consumer> <div className={styles.tag_view}> <div className={styles.tags_container}> <Tags tagList={tagList} closeTag={handleCloseTag} closeAllTag={handleCloseAll} closeOtherTag={handleCloseOther} refreshTag={handleRefreshTag} home={home} /> </div> </div> <div className={styles.child}> <div className={styles.contianbox}> <Scrollbars thumbMinSize={10} autoHide style={{ width: '100%', height: '100%' }} hideTracksWhenNotNeeded={true} > {tagList.map((item) => { return ( <div key={item.path} style={{ display: item.active ? 'block' : 'none', height: '100%' }} > <div key={item.refresh} style={{ height: '100%' }}> {children} </div> </div> ); })} </Scrollbars> </div> </div> </> ); }; export default TagView;