React + Router + Antd实现多标签页功能

参考链接:https://blog.csdn.net/m0_58016522/article/details/121094297

写在前面

最近在学习React,并且开发一个类似于后台管理功能的前端项目,UI用的是阿里的ant design。在后台管理的项目中,其中一个比较实用的功能是多标签的模式,即点击不同菜单可以打开多个不同的Tab,并且点击Tab可以切换不同的页面内容,页面总体布局如下图:


多Tab

在传统的jsp开发的年代,比较流行的一种多标签页的实现方式是用 iframe 实现多标签功能,不过由于iframe有着性能以及兼容性问题,不过由于性能以及兼容性等问题,网页上嵌套iframe的用法逐渐被抛弃。基于以上原因,项目中采用react router和antd主键的方式实现多标签功能。

具体实现

路由配置

项目中有两个主要组件,Login对应的是登录页面,Main对应的是主页面(即登录成功后跳转的页面),另外其他组件为具体的业务组件。在App.tsx中配置以下路由:

            <Provider store={store}>
                <HashRouter>
                    <Switch>
                        <Route path='/login' component={Login} ></Route>
                        <Route exact={false} path='/' component={Main} ></Route>
                    </Switch>
                </HashRouter>
            </Provider>

Login的配置比较简单,对应的路由是/login,即在访问/login时,显示login组件。
Main的路由中配置的路径为/,并且加了exact={false}的属性配置,即访问所有/路径下的子路径(当然除了/login),都会匹配至Main组件。
按以上路由配置时,实际实现的效果是访问/login,显示Login组件,访问/a,显示Main组件,访问/b,还是显示Main组件,另外访问除了/login地址之外的其他任何地址,都是显示Main组件,但是此时地址栏里的地址确实发生变化。

多Tabs标签页实现逻辑

实现逻辑比较简单:用户点击子菜单,首先需要做的是判断打开的tab中有无该菜单页面,有的话显示该tab,没有则添加tab并显示该新tab内容,tab功能比较简单,使用antd的Tabs标签页组件即可(Tabs标签页)。
而此时我们需要做的就是在Main组件中监控路由变化,并根据路由显示出具体的组件即可。

监听路由

React路由history对象提供了一个listen接口,文档如下:

export interface History<HistoryLocationState = LocationState> {
    length: number;
    action: Action;
    location: Location<HistoryLocationState>;
    push(path: Path, state?: HistoryLocationState): void;
    push(location: LocationDescriptor<HistoryLocationState>): void;
    replace(path: Path, state?: HistoryLocationState): void;
    replace(location: LocationDescriptor<HistoryLocationState>): void;
    go(n: number): void;
    goBack(): void;
    goForward(): void;
    block(prompt?: boolean | string | TransitionPromptHook<HistoryLocationState>): UnregisterCallback;
    listen(listener: LocationListener<HistoryLocationState>): UnregisterCallback;
    createHref(location: LocationDescriptorObject<HistoryLocationState>): Href;
}

listen接口参数listener监听方法参数中,其中一个参数为location,其中包含了访问路由地址等信息。listen监听方法中核心实现代码如下:

        this.props.history.listen((location, action) => {
            let {pathname} = location;
            const existFlag = this.props.tabs.findIndex((item: RouteDef) => item.path === pathname) >= 0;
            if (!existFlag) {
                // 添加tab,并显示tab组件内容
            } else {
                // 显示已存在的tab组件内容
            }
        });

另外需要特别考虑的一点就是如果访问的url对应的业务组件不存在,需要显示404页面,在此不展开来讲。
至此多标签功能基本上已完成。

参考链接:https://blog.csdn.net/m0_58016522/article/details/121094297

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容