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

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

相关推荐
moxiaoran575310 分钟前
uni-app萌宠案例学习笔记--页面布局和CSS样式设置
前端·css·uni-app
CrissChan1 小时前
Pycharm 函数注释
java·前端·pycharm
小小小小宇2 小时前
Vue.nextTick()笔记
前端
小约翰仓鼠3 小时前
vue3子组件获取并修改父组件的值
前端·javascript·vue.js
Lin Hsüeh-ch'in3 小时前
Vue 学习路线图(从零到实战)
前端·vue.js·学习
烛阴3 小时前
bignumber.js深度解析:驾驭任意精度计算的终极武器
前端·javascript·后端
计蒙不吃鱼3 小时前
一篇文章实现Android图片拼接并保存至相册
android·java·前端
全职计算机毕业设计4 小时前
基于Java Web的校园失物招领平台设计与实现
java·开发语言·前端
啊~哈4 小时前
vue3+elementplus表格表头加图标及文字提示
前端·javascript·vue.js