React-Native 統一 navigator 路由入口

https://github.com/yj1438/RN-...javascript

背景:RN 試用了一段時間了,其中 navigator 作爲一個核心組件控制着整個 rnApp 的頁面切換。以前寫 demo 和網上見到的一些例子,navigator 使用方式各不相同,多數還都是到切換時纔會從頭引用。以下:前端

圖片描述

感受好不爽,尤爲是頁面稍多、跳轉稍複雜一點後,相互引用,後期要是稍有改動不利於維護。java

作爲一個前端童鞋,用慣了各 SPA 框架強大且優雅的路由控制,真受不了這樣的調用方法。react

借鑑一些前端 spa route 的思想,寫了一個 navigator 統一路由控制。下有詳述。git

設計需求

  1. 全部的頁面 component 都在一個地方控制,這也是基本、不妥協需求;github

  2. 調用簡單明確;app

  3. component 引入設置必定的規範,但不失靈活性;框架

  4. 能夠設定默認的 component 參數。flex

設計思路

思路也很簡單,以下圖:this

圖片描述

下面簡單介紹一下核心兩個文件

app.js

app.js 爲單純的 naivgator 入口,在此定製 navigator 組件。

_renderRoute (route, navigator) {
        // this.route = route;
        this.navigator = navigator;
        return Route.getRoutePage(route, navigator);
    }

    <Navigator
        // 初始頁面
        initialRoute={{
            id: 'homepage',
            params: {}
        }}
        // 路由入口
        renderScene={this._renderRoute.bind(this)}
        configureScene={(route, routeStack) =>
            SceneConfigs.PushFromRight
        }
        sceneStyle={{flex: 1, top: 40}}
        navigationBar={
            <Navigator.NavigationBar
                routeMapper={NavigationBarMap}
                style={{backgroundColor: 'gray', marginTop: 0, height: 40, top: 0}}
            />
        }
    />

利用 initialRouterenderScene 方法分區肯定初始頁面和路由跳轉相應的頁面。

補充知識:每當 naivgator push 時,都會調用 renderScene 方法。並傳入相應參數。

route.js

經過跳轉時 push 傳入的參數,給 navigator 返回相應的 component

'use strict';
import React from 'react';

/**
 * 全部 component 整個框架內只有此處引入
 * navigator 統一進行路由顯示
 * 將所有 component 的引用從老式的層級式改成統一入口的扁平式
 */ 
import Homepage from '../components/homepage';
import List from '../components/list';
import Detail from '../components/detail';
import Error from '../components/error';

/*
 * 路由配置項
 * 可配置默認參數 props: params ,配合 this.props 的限制可以使代碼更嚴謹
 * component 默認和 key 、component 文件夾名稱一致,首字母大寫,component 文件夾內強制 index.js 爲入口文件
 */
const RouteMap = {
    'homepage': {index: 0, component: Homepage, params: {}},
    'list': {index: 1, component: List, params: {}},
    'detail': {index: 2, component: Detail, params: {}}
};

class Route {

    /**
     * 獲取 ID 對應的 Component
     * @param {any} id 頁面的 ID 
     *              有嚴格的映射關係,會根據傳入 ID 同名的文件夾去取路由對應的頁面
     * @param {any} params Component 用到的參數
     */
    static getRoutePage (route, navigator) {
        let id = route.id,
            params = route.params,
            routeObj = RouteMap[id],
            Component;
        if (routeObj) {
            Component = routeObj.component;
            //合併默認參數
            Object.assign(params, routeObj.params);
        } else {
            Component = Error;
            params = {message: '當前頁面沒有找到:' + id};
        }
        return <Component navigator={navigator} {...params} />;
    }     
    
}

export default Route;

在此處,規定 component 按文件夾作爲模塊劃分,(index.js天然成爲入口),RouteMap肯定好路由的關鍵字 id、組件指向、默認參數。

規定 push 傳來的 id 作爲關鍵字,取到相應的 component,而後返回給 NavigatorrenderScene 方法進行跳轉。

這樣,每一個 component 之間不會再有引用關係,無論頁面間的跳轉有多複雜,只需 navigator.push({id: XXX}) 就會跳轉到指定的頁面。

尾記

到此,整體的路由跳轉就結束了。

如今市面好也慢慢出現了一些 RN 的框架,各類問題、坑點也都在不段的完善,之後有新內容再繼續補充完善。

相關文章
相關標籤/搜索