如何实现点击指定卡片的全屏打开(当前双卡片同时触发)
解决方案:实现单卡片独立全屏控制
当前问题的核心是所有卡片共享同一个布尔状态,导致点击任意按钮都会同时切换所有卡片的全屏状态。要实现单卡片独立控制,只需将全局布尔状态改为精准标识当前全屏卡片的状态,具体步骤如下:
1. 修改父组件状态管理
将原来的单个布尔值open,改为存储当前全屏卡片的唯一标识(比如卡片标题、自定义ID):
export const ChartsContainer: FC = () => { // 用字符串存储当前全屏的卡片标识,null表示无卡片全屏 const [fullscreenCard, setFullscreenCard] = useState<string | null>(null); // 通用切换函数:点击时切换指定卡片的全屏状态 const toggleFullscreen = (cardId: string) => { setFullscreenCard(prev => prev === cardId ? null : cardId); }; return ( <div className={styles.chartsContainer}> <Grid container className={styles.panelContainerWrapper} wrap="nowrap"> <Grid item xs={6} className={styles.panelContainer}> <ChartContainer title="title1" // 判断当前卡片是否匹配全屏标识 open={fullscreenCard === "title1"} feature={ <div className={styles.featureWrapper}> <p className={styles.featureText}> {data.chartRequestData.totalRequests.toLocaleString()} </p> <FullScreenButton onClick={() => toggleFullscreen("title1")}> <IconOpenInFull /> </FullScreenButton> </div> } > <> <LineBar data={data.chartRequestData.request} type="line" /> <ChartLegend /> </> </ChartContainer> </Grid> <Grid item xs={6} className={styles.panelContainer}> <ChartContainer title="title2" open={fullscreenCard === "title2"} feature={ <div className={styles.featureWrapper}> <CustomSelect variant="secondary" options={chartSelectOptions} /> <FullScreenButton onClick={() => toggleFullscreen("title2")}> <IconOpenInFull /> </FullScreenButton> </div> } > <LineBar data={data.chartFoivData.request.maxIndicators} type="bar" /> </ChartContainer> </Grid> </Grid> </div> ); };
2. 子组件无需修改
ChartContainer组件保持原有逻辑即可,它仅通过接收的open属性判断是否应用全屏样式:
export const ChartContainer: FC<ChartContainerProps> = ({ feature, title, children, className, open, }) => { return ( <div className={cn(styles.panelWrapper, className, { [styles.panelFull]: open, })} > <div className={styles.headerWrapper}> <h3 className={styles.title}>{title}</h3> {feature} </div> {children} </div> ); };
逻辑说明
- 用
fullscreenCard存储当前全屏的卡片标识(如title1),点击按钮时触发toggleFullscreen函数:- 如果当前全屏的就是该卡片,则清空标识(关闭全屏)
- 如果不是,则设置为该卡片的标识(打开对应卡片全屏)
- 每个
ChartContainer的open属性通过对比自身标识和fullscreenCard的值,决定是否应用全屏样式
扩展:支持多卡片同时全屏
如果需要允许多个卡片同时全屏,可以将状态改为Set类型存储多个标识:
const [fullscreenCards, setFullscreenCards] = useState<Set<string>>(new Set()); const toggleFullscreen = (cardId: string) => { setFullscreenCards(prev => { const newSet = new Set(prev); newSet.has(cardId) ? newSet.delete(cardId) : newSet.add(cardId); return newSet; }); }; // 子组件open属性改为: open={fullscreenCards.has("title1")}
内容的提问来源于stack exchange,提问作者jakiehan
相关产品推荐
相关产品推荐

