ReactNative基础篇-导航路由

1. 背景

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

ReactNative基础篇-导航路由_第1张图片
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 {
  render() {
    return (
        
    )
  }
}

跳转&传参

定义好路由之后,我们就可以尝试跳转了。跳转主要用的是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: ,//自定义中间标题控件
     headerRight: {navigation.getParam('back')}}/>,//自定义左边控件
     headerLeft: ,//自定义右边控件
     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基础篇-导航路由)