美文网首页
ReactNative基础篇-导航路由

ReactNative基础篇-导航路由

作者: Fat_L | 来源:发表于2021-04-11 19:46 被阅读0次

    1. 背景

    通常一个应用不会由单个界面组成,而是由多个模块、多个页面组成。react-navigation的功能就是负责RN导航条管理、页面跳转以及中间的交互过程,这篇文章主要围绕这个方案的使用介绍。

    image.png

    2. 安装

    # 项目根目录安装
    yarn add react-navigation
    # or with npm
    # npm install react-navigation
    npm install --save react-navigation
    npm install --save react-native-gesture-handler
    

    注意:不同RN版本会有特定的配置,例如下面是大于0.60的注意点。
    if you're on React Native >= 0.60, you need to disable autolinking for react-native-gesture-handler first.

    更详细可参考安装教程

    3. 使用

    在react-navigation中有以下类型导航器:

    • StackNavigator: 类似于普通的Navigator,屏幕上方导航栏;
    • TabNavigator: 相当于iOS里面的TabBarController,屏幕下方的标签栏;
    • DrawerNavigator: 抽屉效果,侧边滑出;
    • SwitchNavigator
    • ...

    创建

    几种导航器的创建方式是相似的,这里以创建 StackNavigator 为例。
    现在定义HomeComp组件路由为Home,LoginComp组件路由为Login,LoginComp为默认第一个显示的组件。

    # 创建底部标签栏为: const RootStack = createBottomTabNavigator(...)
    # 创建测滑为: const RootStack = createDrawerNavigator(...)
    
    # 创建上方导航栏
    const RootStack = createStackNavigator(
        {
            Home:{//路由                       
                screen:HomeComp,//对应组件
            },
            Login:{
                screen:LoginComp
            }
        },
        {
            initialRouteName: 'Login',  //第一个显示组件页面,填路由
            //默认全局配置
            // defaultNavigationOptions: {
            //     headerStyle: {
            //         backgroundColor: '#f4511e',
            //     },
            //     headerTintColor: '#fff',
            //     headerTitleStyle: {
            //         fontWeight: 'bold',
            //     },
            // }
    
        }
    )
    const AppContainer = createAppContainer(RootStack);//创建容器
    
    export default class App extends React.Component<IAppProps> {
      render() {
        return (
            <AppContainer />
        )
      }
    }
    

    跳转&传参

    定义好路由之后,我们就可以尝试跳转了。跳转主要用的是StackActions方法,我们可以通过它传入路由和参数进行跳转。

    StackActions.push({routeName, params, action, key})

    根据具体业务的不同,会有不同的跳转行为,StackActions跳转行为有下面几种:

    方法 用法 例子
    push 导航到堆栈中的一个新的路由 [A , B] push C == [A , B , C]
    pop 返回堆栈中的上一个页面 [A, B] pop == [A]
    popToTop 返回堆栈中的第一个页面 [A, B,C] popToTop == [A]
    replace 用新路由替换当前路由 [A , B] replace C == [A , C]
    reset 擦除导航器状态并将其替换为多个操作的结果 [A , B] reset C == [C]

    并且需要我们传入对应参数。

    参数解释
    • routeName:要跳转到的界面的路由名,也就是在createStackNavigator中配置的路由名;
    • params:要传递给下一个界面的参数,可选;
    • action:如果该界面是一个navigator的话,将运行这个sub-action,可选;
    • key:要导航到的路由的可选标识符。 如果已存在,将后退到此路由,可选。
    案例
    # 跳转Home组件&传入参数:
    StackActions.push({routeName:'Home',params:{name:'张三'}})
    # or
    NavigationActions. navigation({routeName:'Home'})
    # or
    this.props.navigation.navigate('Home', { /* params go here */ })
    
    # Home组件获取跳转参数
    const ops = this.props.navigation.getParam('params')
    # or 
    const ops = this.props.navigation.state.params
    

    除此之外,navigationActions也包含部分跳转方法。

    NavigationActions.navigation ({routeName, params, action, key})

    方法 用法 例子
    navigation 跳转到当前堆栈路由里存在的一个页面 [A , B,C, D] navigate B == [A, B]
    Back 返回到上一个页面 [A, B] Back == [A]
    popToTop 返回堆栈中的第一个页面 [A, B,C] popToTop == [A]
    Set Params 设置指定页面的Params **
    Init 初始化一个 state 如果 state 是 undefined **

    header bar设置

    默认导航跳转的页面是不带头部导航栏的,需要我们在组件里面进行设置。
    每个页面组件可以有一个名为navigationOptions的静态属性,它是一个对象或一个返回包含各种配置选项的对象的函数,下面是一个操作实例。

    class Home extends React.Component {
      static navigationOptions = ({ navigation }) => {
        return {
          //title:'标题'
         headerTitle: <headerTitle/>,//自定义中间标题控件
         headerRight: <LeftButton event={()=>{navigation.getParam('back')}}/>,//自定义左边控件
         headerLeft: <RightButton/>,//自定义右边控件
         headerStyle: {
            backgroundColor: '#f4511e',
         },
         headerTintColor: '#fff',
         headerTitleStyle: {
            fontWeight: 'bold',
         },
        };
      };
    
     componentDidMount() {
        this.props.navigation.setParams({ back: this. _back });
      }
    
      _back = () => {
        alert('back')
      };
    }
    

    需要注意的是:

    1. 由于navigationOptions 是个static方法,不能直接拿到this对象里的方法,需要先通过this.props.navigation.setParams设置,navigationOptions里通过navigation.getParam('back')获取。

    2. headerStyle、headerTintColor、headerTitleStyle等属性也可以直接在createStackNavigator全局设置。

    模态跳转

    如果需要模态跳转则需要修改配置。

    const RootStack = createStackNavigator(
      {
        Main: {
          screen: MainStack,
        },
        MyModal: {
          screen: ModalScreen,
        },
      },
      {
        mode: 'modal',
        headerMode: 'none',
      }
    );
    

    4. 多模块跳转

    通常在同一个模块下面不容易出现路由重名的情况,这种情况通常出现在多个模块开发。并且当跳转只写了一个路由名字时,是不清楚跳转到哪个模块下面的页面,缺乏可读性。因此在react-navigation基础上,笔者团队做了一套简单的处理路由的逻辑。

    1. 每一个模块下面会有一个routes.ts的文件。在项目初始化时,会获取所有模块下route.ts文件里定义的路由和对应组件,并根据对应模块名字拼接路由路径。例如在home模块目录有个routes.ts。下面的详情路由经过处理后的真实路由为home/homeDetail。
    # home模块下router.ts文件
    export default [
      {
        path: '/homeDetail',
        component: HomeDetail,
      },
      {
        path: '/home',
        component: Home
      },
    ]
    
    1. 将1步骤中所有处理好的路由和相关配置在createStackNavigator中定义好。

    2. 封装一个负责跳转的类topNavigator(内部是StackActions和navigationActions跳转),对于外部而言传入参数分别为模块名字,路由,参数。

    topNavigator.push(模块名, 路由名, 参数})

    # demo
    topNavigator.push('home', '/homeDetial', {params: params})
    topNavigator.replace(__onamespace, '/add-members', {params: params})
    topNavigator.back()
    
    1. 又或者是每个模块下面再创建一个文件暴露跳转方法,如下示例,这样就基本完成多个模块间的路由跳转问题。
    /**
     *  跳转到首页详情
     */
    export default function goHomeDetail(detailOps: HomeDetaiOps) {
      topNavigator.push(__onamespace, '/homeDetail', { params: detailOps });
    }
    
    # 其他模块文件跳转直接调用goHomeDetail(...)
    

    5. url跳转

    动态解析服务器下发路由也是界面跳转常用的一种方式,因此可以定义一套协议,例如:
    pa://XX/home/homedetail?name='zhangsan'&age=10。客户端做一个专门解析路由的类,将url解析模块名字为home,路由路径为homedetail,参数为name和age,再执行跳转方法。这样就能成功跳转到home模块下面的homeDetail页面,搞定!

    相关文章

      网友评论

          本文标题:ReactNative基础篇-导航路由

          本文链接:https://www.haomeiwen.com/subject/orjqpctx.html