10-8 根据选中类别动态生成首页模块的顶部标签导航器和modal

在之前的章节中,我们已经完成了分类模块的功能。在这一节中,我们将根据用户选择的类别动态生成首页的顶部标签导航器和 Model。

一、动态生成顶部标签导航器

  1. 更新 HomeTabs.tsx 文件

    在 navigator/HomeTab.tsx 文件中,使用 createMaterialTopTabNavigator 创建导航器,并根据用户选择的类别动态生成标签页:

    typescript 复制代码
    import React from 'react';
    import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
    import { connect, ConnectedProps } from 'react-redux';
    import { RootState } from '@/models/index';
    import Home from '@/pages/Home';
    
    export type HomeTabParamList = {
      [key: string]: {
        modelNamespace: string;
        category: string;
      };
    };
    
    const Tab = createMaterialTopTabNavigator<HomeTabParamList>();
    
    const mapStateToProps = ({ category }: RootState) => ({
      myCategorys: category.myCategorys,
    });
    
    const connector = connect(mapStateToProps);
    
    type IProps = ConnectedProps<typeof connector>;
    
    function HomeTabs({ myCategorys }: IProps) {
      return (
        <Tab.Navigator>
          {myCategorys.map((category) => (
            <Tab.Screen
              key={category.id}
              name={category.id}
              component={Home}
              options={{
                tabBarLabel: category.name,
              }}
              initialParams={{
                modelNamespace: category.id,
                category: category.id,
              }}
            />
          ))}
        </Tab.Navigator>
      );
    }
    
    export default connector(HomeTabs);

二、动态生成 Model

  1. 安装 dva-model-extend

    bash 复制代码
    yarn add dva-model-extend
  2. 创建 createModel 函数

    在 models 文件夹中创建一个 createModel.ts 文件:

    typescript 复制代码
    import modelExtend from 'dva-model-extend';
    import home from '@/models/home';
    
    interface Cached {
      [key: string]: number;
    }
    
    const cached: Cached = {
      home: 1,
    };
    
    function registerModel(model: Model) {
      if (!cached[model.namespace]) {
        app.model(model);
        cached[model.namespace] = 1;
      }
    }
    
    export function createModel(namespace: string) {
      const model = modelExtend(home, {
        namespace,
      });
    
      registerModel(model);
    }
  3. 更新 HomeTabs.tsx 文件

    在 HomeTabs.tsx 文件中,动态生成 Model 并绑定到导航器:

    typescript 复制代码
    import { createModel } from '@/models/createModel';
    
    function HomeTabs({ myCategorys }: IProps) {
      myCategorys.forEach((category) => {
        createModel(category.id);
      });
    
      return (
        <Tab.Navigator>
          {myCategorys.map((category) => (
            <Tab.Screen
              key={category.id}
              name={category.id}
              component={Home}
              options={{
                tabBarLabel: category.name,
              }}
              initialParams={{
                modelNamespace: category.id,
                category: category.id,
              }}
            />
          ))}
        </Tab.Navigator>
      );
    }

三、更新页面组件

  1. 更新 Home 页面的 mapStateToProps

    typescript 复制代码
    import { findRouteNameFromNavigatorState } from '@/utils/index';
    
    const mapStateToProps = (
      state: RootState,
      props: { route: { params: { modelNamespace: string } } }
    ) => {
      const { modelNamespace } = props.route.params;
      const modelState = state[modelNamespace];
      return {
        carousels: modelState.carousels,
        channels: modelState.channels,
        hasMore: modelState.pagination.hasMore,
        gradientVisible: modelState.gradientVisible,
        loading: state.loading.effects['home/fetchChannels'],
      };
    };
  2. 创建 findRouteNameFromNavigatorState 函数

    在 utils/index.ts 文件中创建该函数:

    typescript 复制代码
    export function findRouteNameFromNavigatorState(
      state: NavigationState
    ): string {
      let route = state.routes[state.index];
      while (route.state) {
        route = route.state.routes[route.state.index];
      }
      return route.name;
    }

四、总结

在本节中,我们根据用户选择的类别动态生成了首页的顶部标签导航器和 Model。通过使用 dva-model-extend 库,我们能够动态创建 Model,确保每个标签页的数据独立。这样,每个标签页都可以根据选择的类别独立加载和显示数据。

下一节,我们将学习如何实现手势响应系统,完成频道模块的功能。

相关推荐
小码哥_常2 小时前
一套自己部署的 IM,客户端是同一份 Flutter
前端·后端
蜗牛攻城狮5 小时前
微前端四大方案选型对比与最佳实践:qiankun、micro-app、wujie、Module Federation
前端·微前端·qiankun·前端架构·micro-app·wujie
她说可以呀6 小时前
Vue插槽
前端·javascript·vue.js
qq_448011166 小时前
Vue + Jinja2两套模版与法冲突造成undefinedError
前端·javascript·vue.js
aixingpan6 小时前
aixingpan.cn API开发文档:前端查询夏令时和时区接口指南
前端·php
2601_958352907 小时前
23.5×19mm 换掉一整条音频链?|A-68 集成了什么:ADC / DAC / 24.576MHz 时钟 / AEC / 波束降噪,主控仅需 6 根线
前端·音视频·ai降噪·回声消除·语音模块
志尊宝8 小时前
AI原生前端开发(039):AI辅助的Nuxt 4全栈开发
前端·vue.js·ai-native
FRing038 小时前
JavaScript入门到精通三十二(深拷贝、浅拷贝、递归函数)
开发语言·前端·javascript
excel9 小时前
双 Token 与前端使用 Crypto 公私钥鉴权换 Token,哪种方案更好?
前端·后端
外收内放9 小时前
Python基础语法练习题(73)
java·前端·python