react-native-navigation-helper
v0.0.10
Published
easy to use react-native-navigation.
Downloads
2
Maintainers
Readme
react-native-navigation-helper
这个包是对 react-native-navigation 的扩展,它能让你更轻松地在项目中使用 react-native-navigation 。
遇到问题?请反馈到这里。
Usage
首先需安装 react-native-navigation ,可参考这个网址进行安装:
https://wix.github.io/react-native-navigation/#/docs/Installing 。
版本要求 >= 3.2.0,更低版本的没测试过,不确定是否兼容。
使用 npm 安装 react-native-navigation-helper :
npm install react-native-navigation-helper --save
修改项目的启动文件(默认为根目录下的
./index.js
):import $Nav from 'react-native-navigation-helper'; import App from './App'; $Nav.init({ pages: { 'app': App }, layout: { root: { component: { name: 'app' } } } });
$Nav.init(options)
options.defaultOptions:设置默认选项
$Nav.init({
// .......
defaultOptions: {
layout: {
backgroundColor: 'yellow'
}
}
// ......
});
更多可配置参数请参考这里:
https://wix.github.io/react-native-navigation/#/docs/styling?id=options-object-format
options.pages:key-value,项目中的所有页面(Screen)
建议将所有页面文件放在同一个文件夹下,例如 ./pages/
:
|--node_modules
|--pages
| |--index.js
| |--news.js
| |--detail.js
|--package.json
所有页面类都应从 $Nav.Page
继承,否则可能无法使用某些功能:
// import React 是必须的
import React from 'react';
import {View, Text} from 'react-native';
// $Nav 是全局变量,在此文件中不用 import
class News extends $Nav.Page {
constructor(props){
super(props);
}
render() {
return (
<View>
<Text>This is News</Text>
</View>
);
}
}
export default News;
$Nav
是全局变量,除了在 ./index.js
,在其它文件中不用 import
它。
可单独用一个文件来管理所有的页面,例如可以是 ./pages/_.js
:
export default {
// 这里的 key 是你对每个页面的命名
index: require('./index').default,
news: require('./news').default,
detail: require('./detail').default,
// ......
};
则在 ./index.js
中可这样使用:
// ......
import pages from './pages/_';
$Nav.init({
// ......
pages: pages,
// ......
});
options.layout:object or function,基本布局
可以是 object,也可以是返回 object 的 function。
$Nav.init({
// ......
layout: {
root: {
stack: {
children: [{
component: {
name: 'index' // 这里的值是 options.pages 中某个页面对应的 key
}
}]
}
}
}
// ......
});
更多配置可参考这里:
https://wix.github.io/react-native-navigation/#/docs/layout-types
options.promises:array,一组 Promise,一般用来预加载资源
例如,如果要用到 react-native-vector-icons,可在 options.promises
中预加载要用到的图标:
// ......
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
$Nav.init({
// ......
promises: [
MaterialIcons.getImageSource('home', 25),
MaterialIcons.getImageSource('menu', 25)
],
// promises 中每一个 Promise 获取到的数据将依次传入这个 function 中
layout: function(iconHome, iconMenu){
return {
root: {
stack: {
children: [{
component: {
name: 'index'
}
}],
options: {
topBar: {
leftButtons: [{
id: 'btnLeft',
icon: iconMenu
}]
}
}
}
}
};
}
// ......
});
导航
为可点击的元素添加 $href
属性,能轻松实现在页面间的导航:
<View>
<Button title="Click Me" $href="detail"/>
</View>
$href
属性的值可以是 string
,也可以是 object
。
当 $href
属性的值是 string
时,它指的是一个页面的名字(在 options.pages
中设置的)。当用户点击该元素后,将打开这个页面。
react-native-navigation-helper
会根据当前的环境智能地判断是应该使用 push
打开,还是使用 modal
或 overlay
打开。
但开发者的需求是有可能非常态的,如果默认的打开方式不适合你的需求,你可以明确地指定打开方式:
<View>
<Button
title="Click Me"
$href={{
url: 'detail',
type: 'modal'
}}/>
</View>
上面的示例明确地要求以 modal
方式打开 detail
页面。
type
的值可以是 push
、modal
、overlay
。
如果需要传递参数给打开的页面,则使用 data
传递:
<View>
<Button
title="Click Me"
$href={{
url: 'detail',
type: 'modal',
data: {id: 100}
}}/>
</View>
还可以设置在导航后执行的 function:
<View>
<Button
title="Click Me"
$href={{
url: 'detail',
type: 'modal',
data: {id: 100},
afterNav: this.$close
}}/>
</View>
上面的示例在导航后执行 this.$close()
关闭当前面。
如果希望在 js
代码中进行导航,则可用 this.$go(cmd)
:
class Index extends $Nav.Page {
constructor(props) {
super(props);
}
goDetail = () => {
this.$go('detail');
}
render() {
return (
<View>
<Button title="Navigation to Detail" onPress={this.goDetail}/>
</View>
);
}
}
this.$go(cmd)
的参数与 $href
属性的值一样,也可以是 object
:
this.$go({
url: 'detail',
type: 'modal',
data: {id: 100}
});
$Nav.Page
所有的页面都应从 $Nav.Page
继承。
从 $Nav.Page
继承的页面有以下属性、方法:
$close()
关闭当前页面。
$go(options)
导航到指定页面。
$setOptions(options)
options
参数的值参考这里:https://wix.github.io/react-native-navigation/#/docs/styling?id=options-object-formatprops.$opener
当前页面是从哪个页面打开的。
props.$data
opener
打开当前页面时传递过来的参数。
import React from 'react';
import {View, Text, Button} from 'react-native';
class News extends $Nav.Page {
constructor(props){
super(props);
// 当前页面的 opener 传递过来的参数
console.log(props.$data);
}
render() {
return (
<View>
<Text>This is News</Text>
<View>
<Button title="Close" onPress={this.$close}/>
</View>
</View>
);
}
}
export default News;
路由拦截
通过路由拦截,可阻止页面导航或改变导航页面。
在 $Nav.init(options)
参数中配置 beforeNav
,它是一个 function,在页面导航之前执行,它需返回 Promise
或 真
与 假
。
$Nav.init({
// ......
beforeNav: function(fromPage, to, toObj){
if(to == 'profile' && !isAuthorized()){
fromPage.$go({
url: 'login',
type: 'modal'
});
return false;
}
return true;
},
// ......
});
beforeNav
会被传入三个参数,第一个参数 fromPage
是当前页面对象,第二个参数 to
是即将导航到的页面的名字,第三个参数是即将导航到的页面的定义,它是 $Nav.Page class
或 options.layout
中定义的有基本布局的页面(参考后面的文档)。
如果返回的不是 Promise
,返回 假
则阻止导航。
如果返回 Promise
,则 resolve
假
将阻止导航。
sideMenu
sideMenu
有左边栏、右边栏、中间主体部分。其中左边栏和右边栏是可选的。
参考:https://wix.github.io/react-native-navigation/#/docs/layout-types?id=sidemenu
$Nav.init({
// ......
promises: [
MaterialIcons.getImageSource('menu', 25)
],
layout: function(iconMenu){
return {
root: {
sideMenu: {
left: {
component: {
name: 'sidemenuleft'
}
},
center: {
stack: {
children: [{
component: {
name: 'index',
options: {
topBar: {
leftButtons: [{
id: 'btnToggleLeft',
icon: iconMenu
}]
}
}
}
}]
}
}
}
}
};
}
// ......
});
sideMenu
由三个页面组成。在中间主体部分的页面中,可用 this.$toggleLeft()
切换左边栏的显示状态:
class Index extends $Nav.Page {
constructor(props) {
super(props);
}
navigationButtonPressed = ({buttonId}) => {
if (buttonId === 'btnToggleLeft') {
this.$toggleLeft();
}
}
render() {
// ......
}
}
也可用 this.$openLeft()
和 this.$closeLeft()
打开、关闭左边栏。
可用 this.$left
访问左边栏页面对象。
同理,可用 this.$toggleRight()
、this.$openRight()
、this.$closeRight()
切换右边栏显示状态、打开右边栏、关闭右边栏,用 this.$right
访问右边栏页面对象。
在左边栏或右边栏页面中,可用 this.$open()
、this.$close()
打开、关闭自己:
class SideMenuLeft extends $Nav.Page {
render() {
return (
<View>
<Button title="Close" onPress={this.$close}/>
</View>
);
}
}
也可用 this.$center
访问中间主体页面对象。
bottomTabs
在 bottomTabs
的每个选项卡页面中,可用 this.$tab(tabIndex)
切换到指定的选项卡:
<Button title="tab1" onPress={()=>this.$tab(1)}/>
可用 this.$tabsHide()
、this.$tabsShow()
显示、隐藏底部的选项卡栏:
<Button title="hide tabs" onPress={()=>this.$tabsHide()}/>
导航到有基本布局的页面
如果导航的目标页不是简单的 $Nav.Page
,而是由多个 $Nav.Page
组合而成的有基本布局的页面(例如 sideMenu
、bottomTabs
),则需在 $Nav.init(options)
的 layout
中进行配置:
$Nav.init({
// ......
layout: {
root: {
// ......
},
shop: {
bottomTabs: {
children: [{
stack: {
children: [{
component: {
name: 'shopindex'
}
}],
options: {
bottomTab: {
text: 'Shop',
icon: require('./imgs/tab0.png')
}
}
}
}, {
component: {
name: 'orders',
options: {
bottomTab: {
text: 'Orders',
icon: require('./imgs/tab1.png')
}
}
}
}]
}
}
},
// ......
});
之后就可像下面这样导航到上面配置的 shop
页了:
<Button title="Shop" $href="shop"/>
或者:
this.$go({
url: 'shop',
type: 'modal'
});
layout
根节点 key
会被当作页面的名字,因此不能与其它页面的名字重复。
对于打开的由多个页面组成的有基本布局的页面,无法用 this.$close()
关闭它,而应该用 this.$closeWin()
。
$Nav.setOptions(componentId, options)
与 react-native-navigation
中的 Navigation.mergeOptions(componentId, options)
等效。
参考:https://wix.github.io/react-native-navigation/#/docs/styling?id=setting-styles-dynamically 。
在一个页面中,
this.$setOptions({
topBar: {
title: {
text: 'Hello CYF'
}
}
});
与
$Nav.setOptions(this.props.componentId, {
topBar: {
title: {
text: 'Hello CYF'
}
}
});
是等效的。
更多....
react-native-navigation-helper
提供的功能是有限的,可能并不能完全满足你的需求。你可以用 $Nav.nav
直接使用 react-native-navigation
中的 Navigation
对象。当然,你也可以直接在项目中 import react-native-navigation。