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,确保每个标签页的数据独立。这样,每个标签页都可以根据选择的类别独立加载和显示数据。

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

相关推荐
用户938515635076 小时前
从零在浏览器里跑 DeepSeek-R1:WebGPU + Transformer.js 全链路实战
前端·设计模式·typescript
CodeSheep6 小时前
稚晖君公司人事大变动,来了!
前端·后端·程序员
鱼樱前端7 小时前
用 AI 做内容变收入
前端·人工智能·ai编程
浮生望7 小时前
React + TypeScript 组件设计进阶:从类型约束到无状态组件的三次进化
前端
90后的晨仔7 小时前
Mac 开发 uni-app 终极方案:让安卓模拟器彻底脱离 Android Studio 独立运行
前端·vue.js
90后的晨仔8 小时前
别再搞混了!uni-app 中 node_modules 和 uni_modules 到底是什么关系?
前端
kyriewen8 小时前
面试官问"这段逻辑为什么这样写"——我才发现,这半年我写的代码,我自己都解释不了
前端·javascript·面试
谢小飞9 小时前
大文件上传很难?学会这招,GB文件秒传不是梦
前端·node.js
程序员黑豆9 小时前
Windows 系统 Java 环境变量配置全攻略:解决“不是内部或外部命令”
java·前端·ai编程
To_OC9 小时前
别只拿 useRef 绑 DOM 了,搭配 Web Worker 解决页面卡顿才是真的香
前端·react.js·dom