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

xgrn-navigation

v0.7.0

Published

rn容器-路由模块

Downloads

3

Readme

XGNavigation

RN导航框架

功能

原生页面与js页面导航模块

安装

私有库操作

nrm ls

如果提示nrm命令不存在,如下操作

npm install -g nrm

然后增加私有库地址并使用:


nrm add xgnpm  http://172.16.2.71:4873/
nrm use xgnpm
npm install

安装依赖

$ yarn add xgrn-navigation
$ react-native link xgrn-navigation

库升级

$ npm update xgrn-navigation  

项目配置

Android

  1. 修改你的MainApplication改为继承自NavigationApplication:
public class MainApplication extends NavigationApplication implements ReactApplication {
    ...
}

并实现NavigationApplication的抽象方法:

@Override
public boolean isDebug() {
  return BuildConfig.DEBUG;
}
  1. 修改你的MainActivity改为继承自SplashActivity:
public class MainActivity extends SplashActivity {

    /**
     * Returns the name of the main component registered from JavaScript.
     * This is used to schedule rendering of the component.
     */
    @Override
    protected String getMainComponentName() {
        return "";
    }
}

iOS

AppDelegate.m中


#import <XGNavigationController.h>
#import <XGRNBridgeManager.h>

/*------------------------------分割线--------------------------------*/

#pragma mark - 创建应用窗口
- (void)createWindowWithOptions:(NSDictionary *)launchOptions{
  
  // 获取js包的路径
  NSURL *jsCodeLocation;
#ifdef DEBUG
  jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else
  jsCodeLocation = [[TbbUpdateSDK standardSDK] getLocalBundleUrlAtReleasePackage];
#endif
  
  // 配置通用Bridge
  [[XGRNBridgeManager standardManager] loadBridgeWithBundleURL:jsCodeLocation andModuleName:@"jutong" launchOptions:launchOptions];
  
  // 初始化rootViewController
  self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
  self.window.backgroundColor = [UIColor whiteColor];
  self.window.rootViewController = [XGNavigationController createWithLaunchOptions:launchOptions];
  
}

ios原生页面跳转js页面

#import <XGNavigation/XGNavigation.h>
/*------------------------------分割线--------------------------------*/

// 弱引用VC
__weak typeof(self) weakSelf = self;
JSCallBackBlock callBack = ^(NSDictionary * params){
    NSLog(@"%@---%@",params,weakSelf);
  };
[XGNavigation push:@{
                       @"pageType": @"JSPage",
                       @"pagePath": @"classify/GoodsSearchPage",
                       @"params": @{
                              @"onSubmitCallBack": callBack,
                           }
                       }
         andAnimated:YES];

JS页面代码规范示例

为了自动将应用路由信息标准格式化传递给电商配置中台。 项目中JS页面编写时应当遵循并定义如下参数规范:

页面props参数规范
static propTypes = {
    id: PropTypes.string.isRequired,
    name: PropTypes.string,
};

页面props参数描述
static propTypesDesc = {
    id: '商品id',
    name: '商品名称',
};

电商配置中台 和 是否需要登录 配置参数
static xgNavigationBarOptions = {
    needLogin: true,                //进入该页面是否需要登录
    showOnCMS: true,                //是否允许CMS配置中台配置跳转
    cmsPageTitle: '商品搜索页面',     //CMS展示的页面名称
    pageName: 'GoodsSearchPage',    //路由子path
};
当且仅当showOnCMS为true时,该页面才会加入路由上传表中,方可同步到CMS上。

用法

  1. 按要求写好文件层级,便于navigation识别你的js文件路径

  2. 修改你的入口App.js文件.仅用于根据配置生成一些的JSView,页面是大家在js中写的page。

//导入XGNavigation
import XGNavigation from 'xgrn-navigation';

export default class App extends Component<{}> {

    render() {
        //查询是否匹配路由
        const page = XGNavigation.renderPageByConfig(this.props);
        if (page && page !== 404) {
            return page;
        } else if (page == 404) {
            return (
                <View style={styles.container}>
                    <Text style={styles.welcome} onPress={this._onPress}>
                        {`App not found 404`}
                    </Text>
                </View>
            );
        }
        return (<LoadingView/>);
    }
}

3.路由跳转

XGNavigation会自动为你的每个子页面添加key为navigation的props属性,因此在你的页面中这样使用:

const {navigation} = this.props;
navigation.push({
    pagePath: home/HomePage
})

###API介绍

1.pageType

作用:获取支持的页面类型

返回值:

return {
            JSPage: 'JSPage',               // JS页面
            NativePage: 'NativePage',       // 原声页面
            NativeTabPage: 'NativeTabPage', // 原声tab页面
        };

2.transitionsConfig

作用:获取支持的转场动画类型

返回值:

return {
            FromRight: 'FromRight',  // 从右到左
            FromBottom: 'FromBottom',// 从下到上
        };

3.appRoutes

作用:app注册的所有JS路由栈

返回值:

{}

5.initializeRoutes(routeConfig)

作用:初始化项目js页面路由信息

使用示例:@param routeConfig

XGNavigation.initializeRoutes([
    home,       //首页
    classify,   //分类
    shopping,   //购物车
    mine,       //我的
    debug,      //调试工具
    XGAuth      //登录、注册
]);

6.match(pathPath)

作用:根据pathPath匹配到页面组件

参数
@param pathPath 页面路由
返回值
组件Component或null

7.renderPageByConfig(initParams)

作用:根据初始化参数返回页面

参数
@param initParams
返回值
@return {*} 返回值可能为一个组件,也可能为404,如果initParams不存在pagePath返回null

8.resetRoot(pageConfig, animated)

作用:重置整个路由栈

@param pageConfig
    .pageType               String.页面类型:默认是JSPage,目前仅支持(JSPage,NativePage,NativeTabPage)
    .transitionsConfig      String.转场动画配置:默认是FromBottom,目前仅支持(FromRight,FromBottom,FromTop)
    .pagePath               String.页面路径(当pageType为JSPage,NativePage时需要需要指定页面初始化参数,代表js中页面的文件路径、或ios中viewcontroller的class名称、或android中active的class名称)
                    pagePath支持Object{ios: 'DemoViewController',android:'DemoActivety'}
    .params                 Object.页面初始化参数,可为空(当pageType为JSPage,NativePage时需要需要指定页面初始化参数)
    .tabConfigs             Tab配置(当且仅当pageType===NativeTabPage)
    .selectedIndex          默认选中的tab栏(可选)
    .tabCount               多少个tab(__ANDROID__)
    .tintColor              选中的Icon和title的颜色,可选项
    .unselectedItemTintColor 未选中Icon和title的颜色,可选项
    .barTintColor           tabbar的颜色,可选项
    .barTranslucent: false, tabbar半透明选项,barTintColor有值则该选项无效,效果不透明 (__IOS__)
    .pages                  Array<itemParams>.tab每一个item的配置
        .pageType               数据类型同上(此时不在支持NativeTabPage)
        .pagePath               数据类型同上
        .params                 数据类型同上
        .selectTabBarIcon       tab选中icon
        .unSelectTabBarIcon     tab非选中的icon
        .tabBarTitle            tab对应的title
@param animated 是否带动画

9.addPushPageInterceptor(pushInterceptor)

作用:添加页面push跳转拦截器函数(目前仅支持js调用时,能进行拦截)

使用示例:
@param targetPageComponent 待跳转页面Component
@param actionPush          继续执行跳转动作函数
XGNavigation.addPushPageInterceptor((targetPageComponent,actionPush)=>{
    const {needLogin} = targetPageComponent.xgNavigationBarOptions || {};
    if (needLogin && !userMobx.phone){
        setTimeout(()=>{
            actionPush();
        },1000);
        return false;
    }
    return true;
});

10.getRouteStack()

作用:获取整个路由栈信息

返回为一个route数组:

[{
    pagePath: 'TMMarketTabPage',
    pageType: 'NativeTabPage',
    uniqueId: 'xxxxx',          //唯一id
    index: 0,
    tabs: [{...}, {...},数据结构同下]
},
{
    pagePath: 'TMMarketTabPage',
    pageType: 'JSPage',
    uniqueId: 'xxxxx',
    index: 1,
},
{
    pagePath: 'TMMarketTabPage',
    pageType: 'NativePage',
    uniqueId: 'xxxxx',
    index: 2,
}]

10.push(pageConfig, animated)

作用:push进入下一个页面(原生或者ios),一般情况下只需要填下pagePath,剩下的参数会自动补全

@param pageConfig Object Required
         .pageType          String.页面类型:默认是JSPage,目前仅支持(JSPage,NativePage,NativeTabPage)
         .transitionsConfig String.转场动画配置:默认是FromBottom,目前仅支持(FromRight,FromBottom,FromTop)
         .pagePath          String.页面路径(当pageType为JSPage,NativePage时需要需要指定页面初始化参数,代表js中页面的文件路径、或ios中viewcontroller的class名称、或android中active的class名称)
             pagePath支持Object{ios: 'DemoViewController',android:'DemoActivety'}
         .params            Object.页面初始化参数,可为空(当pageType为JSPage,NativePage时需要需要指定页面初始化参数)
         .tabConfigs        Tab配置(当且仅当pageType===NativeTabPage)
            .selectedIndex      默认选中的tab栏(可选)
            .tabCount           多少个tab(__ANDROID__)
            .tintColor          选中的Icon和title的颜色,可选项
            .unselectedItemTintColor 未选中Icon和title的颜色,可选项
            .barTintColor       tabbar的颜色,可选项
            .barTranslucent: false, // tabbar半透明选项,barTintColor有值则该选项无效,效果不透明 (__IOS__)
            .pages       Array<itemParams>.tab每一个item的配置
                 .pageType           数据类型同上(此时不在支持NativeTabPage)
                 .pagePath           数据类型同上
                 .params             数据类型同上
                 .selectTabBarIcon   tab选中icon
                 .unSelectTabBarIcon tab非选中的icon
                 .tabBarTitle        tab对应的title

11.replaceStackTopRoute(pageConfig,animated)

作用:替换栈顶页面

@param pageConfig    新页面配置(具体内容同push函数的pageConfig)
@param animated      是否需要动画

12.pop(animated)

作用:返回上一级页面

@param animated 是否带动画

13.popToRoute(route, animated)

作用:返回到指定页面,每个子页面可使用this.props.route获取自己的route。

@param animated 是否带动画(ANDROID默认动画,不支持animated参数)

14.popToRoot(animated)

作用:返回到路由栈底

@param animated 是否带动画(ANDROID默认动画,不支持animated参数)

15.setTabBarSelectedIndex(route, newIndex)

作用:设置tab页面选中的index

@param route     当前tab子页面的route
@param newIndex  需要选中的下标
注意:如果当前route对应的页面并不存在于Tab容器里,则不执行任何效果

16.isChildTab(route)

作用:判断页面是否处于tab容器中

@param route 当前页面的route
@return {Promise.<bool>} 是否为tab容器里的子页面

17.showLaunchImageOnWindow()

作用:主动添加LaunchImage在window上进行占位显示((如果当前splash已经在展示中,则doNothing)

18.removeLaunchImageFromWindow()

作用:主动从window上移除LaunchImage((如果LaunchImage不存在,则doNothing)

19.allowPopGestureRecognizer(route)

作用:开启关闭侧滑手势(仅支持IOS)

@param route             路由
@param allowPopGesture   侧滑手势是否打开
如果route为tabbar上面的一个子页面,则allowPopGesture对tabbar生效

原生和JS页面跳转,携带函数问题和回到函数问题。

this.props.navigation.push({
    pageType: this.props.navigation.pageType.NativePage,
    pagePath: {//原生页面的文件名
        ios: 'WebController',
        android: 'com.xg.jsbridge.WebViewFragment',
    },
    params: {
        url: 'https://www.baidu.com',
        jumpCallBack: (obj)=>{
            console.warn(obj)
        }
    },
});

弹框。

首先要全局初始化注入组件。

// 初始化弹框(仅限即支持原声调用、又支持JS调用)
XGNavigation.initializeAlert([
    AcquireCouponsAlert
]);
组件内部要书写,这样方便通过字符串的alertPath映射到组件
static alertPath = 'AcquireCouponsAlert';
放置到当期ViewController的View上,或当前frament上,(ios可以侧滑退出)
this.props.navigation.alert({
            alertPath: 'AcquireCouponsAlert',//这个弹框组件所书写的static alertPath
            bindRoute: this.props.route,
            params:{
                //组件props的属性
                spuIdList: this.spuList,
                type: 'ShopCar',
                pickerNewCoupons: ()=>{
                    //用户在优惠券弹框内选择了新的弹框,刷新优惠券提示语(静默,不loading)
                    this._getCouponTipInfo(this.totalAmount);
                }
            }
});
放置到当期NavigationController的View上或window上,或当前Activity上,(ios 不可以侧滑退出) 
this.props.navigation.alert({
            alertPath: 'AcquireCouponsAlert',//这个弹框组件所书写的static alertPath
            bindRoute: this.props.route,
            params:{
                  //组件props的属性
                  spuIdList: this.spuList,
                  type: 'ShopCar',
                  pickerNewCoupons: ()=>{
                        //用户在优惠券弹框内选择了新的弹框,刷新优惠券提示语(静默,不loading)
                        this._getCouponTipInfo(this.totalAmount);
                  }
            }
});

导航条配置与页面基础状态管理

为了方便业务层能够快速构建页面,toast/alert/loading能力,不用太多的关注页面加载中、加载失败、加载成功的切换, 或单个组件的加载状态(加载中、加载失败、加载成功),以及导航条最基础的配置。 在初始化基础路由配置以后:

XGNavigation.initializeJSRoutes([
    home,       //首页v1.1.1
    coupons,    //优惠券
    productList,//商品列表
    shopping,   //购物车
    mine,       //我的
    debug,      //调试工具
    cmsPage,    //CMS页面
    XGAuth,     //登录、注册
    poi,        //poi地址搜索
]);

框架内部会对每一个路由页面的Component进行重写,在Component的原型链中添加toast/alert/loading能力。 具体可以浏览PageDecorator文件源码。

  /* -------------toast-------------  */
  target.prototype.xg_toastShow = function (title, params) {
    if (!this.xg_toast) {
      return;
    }
    this.xg_toast.showToast(title, params || {});
  };
  target.prototype.xg_toastDismiss = function (callBack) {
    if (!this.xg_toast) return;
    this.xg_toast.dismiss(typeof callBack === 'function' ? callBack : null);
  };
  target.prototype.xg_isToastShow = function () {
    if (!this.xg_toast) return false;
    return this.xg_toast.isToastShow();
  };


  /* -------------loading----------  */
  target.prototype.xg_loadingShow = function (msg, params) {
    if (!this.xg_loadingHub) return;
    this.xg_toastDismiss();
    this.xg_loadingHub.loadingShow(msg, params || {});
  };
  target.prototype.xg_loadingDismiss = function (callBack) {
    if (!this.xg_loadingHub) return;
    this.xg_loadingHub.dismiss(typeof callBack === 'function' ? callBack : null);
  };
  target.prototype.xg_isLoadingShow = function () {
    if (!this.xg_loadingHub) return false;
    return this.xg_loadingHub.isLoadingShow();
  };


  /* -------------alert----------  */
  target.prototype.xg_alertShow = function (params) {
    this.xg_alertView && this.xg_alertView.alertShow(params);
  };
  target.prototype.xg_alertDismiss = function (callBack) {
    this.xg_alertView &&  this.xg_alertView.dismiss(callBack);
  };
  target.prototype.xg_isAlertShow = function () {
    if (!this.xg_alertView) return false;
    return this.xg_alertView.isAlertShow();
  };



  /* -------------XGNavigatorBar-------------  */
  target.prototype.xg_NavigationBarHiddenLeftItem = function (hidden, callBack) {
    //隐藏左边item
    if (!this.xg_navigatorBar) return;
    this.xg_navigatorBar.hiddenLeftItem(hidden, callBack);
  };
  target.prototype.xg_NavigationBarHiddenRightItem = function (hidden, callBack) {
    //隐藏右边item
    if (!this.xg_navigatorBar) return;
    this.xg_navigatorBar.hiddenRightItem(hidden, callBack);
  };
  target.prototype.xg_NavigationBarResetTitle = function (newTitle, callBack) {
    //更换title
    if (!this.xg_navigatorBar) return;
    this.xg_navigatorBar.changeTitle(newTitle, callBack);
  };

这样这些组件就有了基础的动态设置导航和loading/alert/toast能力。 其实就是底层重写了组件本身的render函数

  const targetRender = ComponentClass.prototype.render;
  ComponentClass.prototype.render = function () {

    const {renderByPageState} = xgNavigationBarOptions;

    let controlParams = null;

    if (renderByPageState) {
      try {
        controlParams = this.xg_getPageStateOptions();
      } catch (error) {
        console.warn('when you set true, you need implementation xg_getPageStateOptions function to return your page state');
        controlParams = {};
      }
    }

    const that = this;

    return (<View style={styles.container}>

      <XGNavigatorBar {...xgNavigationBarOptions}
        leftPressed={()=> (this.xg_NavigationBarLeftPressed || xgNavigationBarDefaultLeftPressed).call(this)}
        rightPressed={()=>(this.xg_NavigationBarRightPressed || xgNavigationBarDefaultRightPressed).call(this)}
        ref={(bar)=>{this.xg_navigatorBar = bar;}}/>

      {
        renderByPageState ? renderViewByLoadingState(controlParams, () => {
          return targetRender.call(that);
        }) : targetRender.call(this)
      }

      <AlertView ref={(alertView) => {this.xg_alertView = alertView;}}/>

      <ToastView ref={(toast) => {this.xg_toast = toast;}}/>

      <LoadingHub ref={(loadingHub) => {this.xg_loadingHub = loadingHub;}}/>

    </View>);
  };

对于页面组件,要求大家书写static xgNavigationBarOptions配置。用于配置基础导航条,路由信息等。。。

如果需要设置页面状态管理

在xgNavigationBarOptions配置中renderByPageState设置为true 组件需要实现xg_getPageStateOptions函数,返回当前想要渲染的页面内容。 例如: 具体可以参考PageState文件实现

/**
     * 返回当前页面状态,应该有的状态
     * @return object 页面当前应该展示的状态
     */
    xg_getPageStateOptions = ()=>{
        return {
            loadingState: this.state.loadingState,
            emptyProps: {
                description: `暂无可用的优惠券`,
                isScrollViewContainer: true,
                isRefresh: this.state.refreshing,
                source: EmptyImg,
                onRefresh: this._onRefresh,
            },
            netFailedProps: {
                netFailedInfo: this.state.error,
                callback: () => {
                    this.setState({
                        loadingState: PageLoadingState.loading
                    },()=>{
                        this._loadDataFirstPage();
                    });
                }
            }
        };
    };