npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-native-navigation-helper

v0.0.10

Published

easy to use react-native-navigation.

Downloads

18

Readme

react-native-navigation-helper

这个包是对 react-native-navigation 的扩展,它能让你更轻松地在项目中使用 react-native-navigation 。

遇到问题?请反馈到这里

Usage

  1. 首先需安装 react-native-navigation ,可参考这个网址进行安装:

    https://wix.github.io/react-native-navigation/#/docs/Installing

    版本要求 >= 3.2.0,更低版本的没测试过,不确定是否兼容。

  2. 使用 npm 安装 react-native-navigation-helper :

    npm install react-native-navigation-helper --save
  3. 修改项目的启动文件(默认为根目录下的 ./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 打开,还是使用 modaloverlay 打开。

但开发者的需求是有可能非常态的,如果默认的打开方式不适合你的需求,你可以明确地指定打开方式:

<View>
    <Button
        title="Click Me"
        $href={{
            url: 'detail',
            type: 'modal'
        }}/>
</View>

上面的示例明确地要求以 modal 方式打开 detail 页面。

type 的值可以是 pushmodaloverlay

如果需要传递参数给打开的页面,则使用 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 继承的页面有以下属性、方法:

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 classoptions.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 组合而成的有基本布局的页面(例如 sideMenubottomTabs),则需在 $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。