官方提供了兩種導(dǎo)航器:Navigator和NavigatorIOS渐苏,后者只能在iOS平臺(tái)使用掀潮,而前者是可以兼容Android和iOS平臺(tái)的,詳細(xì)介紹請參考官方介紹琼富。
基本使用方式:
- initialRoute:初始化路由仪吧,指定第一個(gè)頁面
- configureScene:配置頁面切換場景
- renderScene:渲染場景,返回需要顯示的頁面
常見的一個(gè)寫法:
// ...
import FirstPage from './FirstPage';
class Demo10 extends Component {
render() {
return (
<Navigator
style={{flex: 1}}
initialRoute= {{id: 'FirstPage', component: FirstPage}}
configureScene= {this.configureScene}
renderScene= {this.renderScene}
/>
);
}
configureScene(route, routeStack) {
if (route.sceneConfig) { // 有設(shè)置場景
return route.sceneConfig;
}
return Navigator.SceneConfigs.PushFromRight; // 默認(rèn)鞠眉,右側(cè)彈出
}
renderScene(route, navigator) {
return <route.component {...route.passProps} navigator= {navigator}/>;
}
}
// ...
initialRoute薯鼠、configureScene、renderScene
三個(gè)方法都和一個(gè)重要的參數(shù)route
有關(guān)聯(lián)械蹋。
route:表示路由對象的信息出皇,我們看下它包含哪些參數(shù)
export interface Route {
component?: React.ComponentClass<ViewProperties> // 必要參數(shù),目標(biāo)頁面
id?: string // 通常用來設(shè)置一個(gè)與component匹配的標(biāo)識(shí)
title?: string // 常用來設(shè)置component頁面的標(biāo)題參數(shù)
passProps?: Object; // 用來傳遞參數(shù)
//anything else
[key: string]: any
//Commonly found properties
backButtonTitle?: string // 標(biāo)題欄左邊按鈕文字
content?: string
message?: string;
index?: number
onRightButtonPress?: () => void // 標(biāo)題欄右邊按鈕點(diǎn)擊事件
rightButtonTitle?: string // 標(biāo)題欄右邊按鈕文字
sceneConfig?: SceneConfig // 切換場景的參數(shù)
wrapperStyle?: any
}
本篇文章我們會(huì)使用到id哗戈、component郊艘、passProps、sceneConfig
這四個(gè)參數(shù)谱醇,其他類似于backButtonTitle暇仲、onRightButtonPress
等,這些參數(shù)在使用通用導(dǎo)航欄的時(shí)候會(huì)用到副渴。
實(shí)際項(xiàng)目中奈附,這種方式基本不會(huì)用,因?yàn)闃I(yè)務(wù)的復(fù)雜等原因會(huì)導(dǎo)致通用導(dǎo)航欄變得越來越臃腫煮剧,不可維護(hù)斥滤,如果想了解的同學(xué),可以參考這篇文章勉盅。
Navigator和其他平臺(tái)的導(dǎo)航一樣佑颇,也是使用“棧”的形式來維護(hù)頁面草娜。我們都知道“椞粜兀”是先進(jìn)后出的原則,Navigator多數(shù)API是“遵循”這個(gè)原則的宰闰。
不同的是茬贵,Navigator還提供了更加靈活的API簿透,使得我們可以從類似“棧頂”跳轉(zhuǎn)到“棧底”,同時(shí)還能保持“棧底”以上的頁面存在而不銷毀解藻,我覺得可以用“偽椑铣洌”來形容它。
常用API
- push(route) - 跳轉(zhuǎn)到新的場景螟左,并且將場景入棧啡浊,你可以稍后跳轉(zhuǎn)過去
- pop() - 跳轉(zhuǎn)回去并且卸載掉當(dāng)前場景
- popToTop() - pop到棧中的第一個(gè)場景,卸載掉所有的其他場景胶背。
- popToRoute(route) - pop到路由指定的場景巷嚣,在整個(gè)路由棧中,處于指定場景之后的場景將會(huì)被卸載奄妨。
- jumpBack() - 跳回之前的路由涂籽,當(dāng)然前提是保留現(xiàn)在的,還可以再跳回來砸抛,會(huì)給你保留原樣评雌。
- jumpForward() - 上一個(gè)方法不是調(diào)到之前的路由了么,用這個(gè)跳回來就好了直焙。
- jumpTo(route) - 跳轉(zhuǎn)到已有的場景并且不卸載景东。
備注:與push&popxxx效果類似,只是不會(huì)卸載場景
- replace(route) - 用一個(gè)新的路由替換掉當(dāng)前場景
- replaceAtIndex(route, index) - 替換掉指定序列的路由場景
- replacePrevious(route) - 替換掉之前的場景
備注:replacexxx:僅僅替換場景奔誓,并不會(huì)跳轉(zhuǎn)
- resetTo(route) - 跳轉(zhuǎn)到新的場景斤吐,并且重置整個(gè)路由棧
- immediatelyResetRouteStack(routeStack) - 用新的路由數(shù)組來重置路由棧
- getCurrentRoutes() - 獲取當(dāng)前棧里的路由,也就是push進(jìn)來厨喂,沒有pop掉的那些和措。
為了演示以上API的使用,我們新建三個(gè)js文件蜕煌,FirstPage.js
派阱、SecondPage.js
和ThirdPage.js
。
FirstPage
作為導(dǎo)航控制器的根頁面斜纪,請參考文章開頭給出的代碼示例贫母。
push&popxxx:
1、FirstPage->push->SecondPage:傳遞參數(shù)from
// FirstPage.js
_push()
{
this.props.navigator.push({
id: 'SecondPage',
component: SecondPage,
passProps: {
from: 'First Page'
},
sceneConfig: Navigator.SceneConfigs.HorizontalSwipeJump
});
}
2盒刚、SecondPage->push->ThirdPage腺劣,代碼類似就不貼了。然后因块,ThirdPage->pop->SecondPage琳钉,返回上一個(gè)頁面
// ThirdPage.js
_pop()
{
this.props.navigator.pop();
}
3翘地、ThirdPage->popToTop->FirstPage堡距,返回第一個(gè)頁面
// ThirdPage.js
_popToTop() {
this.props.navigator.popToTop();
}
4、ThirdPage->popToRoute->FirstPage寨辩,返回第一個(gè)頁面
// ThirdPage.js
_popToRouteById(id) {
var destRoute;
this.props.navigator.getCurrentRoutes().map((route, i) => {
if (route.id === id) {
destRoute = route;
}
});
// 攜帶參數(shù)
destRoute.passProps = {from: 'Third Page'};
this.props.navigator.popToRoute(destRoute);
}
效果圖如下:
jumpxxx:
1、SecondPage->jumpBack->FirstPage:返回上一個(gè)場景歼冰,并且不卸載當(dāng)前場景
// SecondPage.js
_jumpBack() {
this.props.navigator.jumpBack();
}
2、FirstPage->jumpForward->SecondPage:與jumpBack配套使用耻警,返回觸發(fā)jumpBack的場景
// FirstPage.js
_jumpForward()
{
this.props.navigator.jumpForward();
}
效果圖如下:
我們打印下
FirstPage
和SecondPage
的生命周期函數(shù)componentDidMount
和componentWillUnmount
隔嫡。
// FirstPage.js
componentDidMount() {
console.log("FirstPage: componentDidMount");
}
componentWillUnmount() {
console.log("FirstPage: componentWillUnmount");
}
// SecondPage.js
componentDidMount() {
console.log("SecondPage: componentDidMount");
}
componentWillUnmount() {
console.log("SecondPage: componentWillUnmount");
}
我們看到,在來回的跳轉(zhuǎn)過程中
SecondPage
并沒有被卸載甘穿。
更有趣的是腮恩,從SecondPage
jumpBack
之后。在FirstPage
頁面温兼,如果點(diǎn)擊push
秸滴,你會(huì)發(fā)現(xiàn)舊的SecondPage
會(huì)被卸載,然后會(huì)創(chuàng)建一個(gè)新的SecondPage
募判。console如下:
3荡含、SecondPage->jumpTo->FirstPage:跳轉(zhuǎn)到一個(gè)已存在的場景,并且不卸載當(dāng)前場景
// SecondPage.js
_jumpToById(id) {
var destRoute;
this.props.navigator.getCurrentRoutes().map((route, i) => {
if (route.id === id) {
destRoute = route;
}
});
// 攜帶參數(shù)
destRoute.passProps = {from: 'Second Page'};
this.props.navigator.jumpTo(destRoute);
}
replacexxx:
新建一個(gè)場景FourthPage.js
届垫。當(dāng)前“検鸵海”里面的場景為FirstPage->SecondPage->ThirdPage
。
1装处、ThirdPage ->replacePrevious:在ThirdPage
頁面替換上一個(gè)場景(也就是SecondPage
)為FourthPage
误债。
// ThirdPage.js
_replacePrevious()
{
this.props.navigator.replacePrevious({
id: 'FourthPage',
component: FourthPage,
});
}
此時(shí),“椡ǎ”里面的場景為FirstPage->FourthPage->ThirdPage
寝蹈。
2、replace(route)
和replaceAtIndex(route, index)
與replacePrevious
非常類似登淘,只是替換的場景不同而已箫老,這里不做講解,大家自己測試一下就知道效果了形帮。
- replace(route) - 用一個(gè)新的路由替換掉當(dāng)前場景
- replaceAtIndex(route, index) - 替換掉指定序列的路由場景
需要注意的是槽惫,replacexxx:僅僅替換場景,并不會(huì)跳轉(zhuǎn)辩撑。
resetTo:
跳轉(zhuǎn)到新的場景界斜,并且重置整個(gè)路由棧。
想象這樣一個(gè)場景合冀,我們有個(gè)App各薇,用戶登錄之后,可能已經(jīng)進(jìn)入三級頁面,此時(shí)用戶希望切換用戶重新登錄峭判,這時(shí)候我們就需要跳轉(zhuǎn)到登錄頁面开缎,并且清空其他所有頁面。
此時(shí)林螃,就需要使用到resetTo奕删。
我們在ThirdPage->resetTo->FourthPage,然后在FourthPage
使用pop
疗认,看下是否還有其他頁面存在完残。
// ThirdPage.js
_resetTo()
{
this.props.navigator.resetTo({
id: 'FourthPage',
component: FourthPage,
});
}
// FourthPage.js
_pop()
{
this.props.navigator.pop();
}
效果圖如下:
我們看到整個(gè)路由“棧”被重新初始化横漏,FourthPage
成為“椊魃瑁”的根頁面。
immediatelyResetRouteStack(routeStack):
用新的路由數(shù)組來重置路由棧缎浇,與resetTo類似扎拣,只不過resetTo參數(shù)為一個(gè)對象,而immediatelyResetRouteStack(routeStack)為一個(gè)數(shù)組素跺,感興趣的同學(xué)可以自己嘗試一下效果二蓝。
本文的源碼地址:Demo10