工程配置
npm会解析package.json,并下载依赖的包
{
"name": "HelloWorld",
"version": "0.0.1",
"appVersion": "7.20",
"private": true,
"scripts": {
"start": "crn-cli start",
"android": "crn-cli run-android",
"ios": "crn-cli run-ios"
},
"dependencies": {
"@ctrip/crn": "git+http://wirelesscode.ctripcorp.com/crn#rel/7.2",
"react": "15.4.2",
"react-native": "0.41.0"
}
}
基于 CRN(Ctrip React-Native)框架开发快速入门
@ctrip/crn: 是Ctrip React Native框架,由无线基础研发团队基于React Native框架开发的适用于携程App业务开发的框架,可逐步取代App开发中Hybrid以及Native技术,支持iOS/Android平台,即两套平台使用同一套业务代码。CRN框架的目标是能够使用JS语言开发出媲美Native用户体验的App。
- @crip/crn模块引入
- 路由配置
- Index 入口 & App 初始化
- APP 注册
- main.js:完整入口页面
- 页面(Page)开发
- 导航
- 导航栏
- Native-RN-Hybrid 页面跳转
- 性能注意点
- 资源优化
- CRN 版本
- 其他约定
@crip/crn模块引入
HelloWorld/main.js
import {
AppRegistry
} from 'react-native';
import React, {Component} from 'react';
import {
App
} from '@ctrip/crn';
路由配置
HelloWorld/main.js
isInitialPage为true表示是首页
import page1 from 'Page1.js';
import page2 from 'Page2.js';
import page3 from 'Page3.js';
const pages = [
{
component:page1,
name:'page1',
title:'Page1 标题',
isInitialPage:true
},
{
component:page2,
title:'Page2 标题',
name:'page2'
},
{
component:page3,
title:'Page3 标题',
name:'page3'
},
];
导航栏全局配置
该选项配置NavigationBar,默认不隐藏,但是强烈建议hide设置为true,并且使用CRN的HeaderView组件自定义头部,或许在未来的某个时候,hide就会默认为true了,新手入门不必在意这些
HelloWorld/main.js
const navigationBarConfig = {
hide:false, // 默认为 false
backgroundColor:'rgb(1, 100, 200)', // 导航栏背景色,默认为携程蓝(9, 159, 222)
};
class HelloWorld extends App {
constructor(props) {
super(props);
this.init({pages, navigationBarConfig});// navigationBarConfig 可不传,会使用默认值
}
}
AppRegistry.registerComponent('HelloWorld', () =
>
HelloWorld);
Index 入口 & App 初始化
项目创建自动生成的,了解这里是入口就可以了
HelloWorld/main.js
class HelloWorld extends App {
constructor(props) {
super(props);
this.init({pages, navigationBarConfig});
}
}
APP 注册
HelloWorld/main.js
AppRegistry.registerComponent('HelloWorld', () =
>
HelloWorld);
main.js:完整入口页面
HelloWorld/main.js
'use strict';
import React, { Component } from 'react';
import {
App
} from '@ctrip/crn';
import page1 from './src/Page1.js';
import page2 from './src/Page2.js';
const pages = [
{
component:page1,
name:'page1',
isInitialPage:true
},
{
component:page2,
name:'page2',
}
];
//全局导航栏配置
const navigationBarConfig = {
hide:false, // 默认为 false
backgroundColor:'rgb(9, 159, 222)', // 导航栏背景色,默认为携程标准蓝 rgb(9, 159, 222)
};
class HelloWorld extends App {
constructor(props) {
super(props);
this.init({pages, navigationBarConfig});// navigationBarConfig 可不传
}
}
module.exports = HelloWorld;
平台入口
这是为方便使用原生打包脚本进行打包运行而创建两个平台特性的入口文件,不需要理会:
iOS:
//index.ios.js
import './index.js';
android:
//index.androd.js
import './index.js';
页面(Page)开发
可以将Page看做页面的容器,子元素的布局都集中到Page中,Page默认有:
- 默认导航栏
- 导航
- PV半自动埋点
- 页面切换性能优化
- android 物理返回键处理
//Page1.js
export default class Page1 extends Page {
constructor(){
super(props);
this.page.title = 'Page1 title';
}
pageId() { // PV 埋点使用
return '123';
}
pageInfo() { // PV 埋点附带的额外参数
return {'foo':'bar'};
}
render() {
return (
<
ViewPort
>
<
View
>
<
Text
>
Hello World
<
/Text
>
<
/View
>
<
/ViewPort
>
);
}
}
导航
- push
进入页面page2
,前提是page2在main.js的pages中注册过
this.push('page2',{data:xxx,callback:()={}});
参数传递
page2:下一个页面名称(App 初始化时配置)
{data:xxx}:第二个参数为带到下一个的参数,透传,下一个页面通过 this.props 取到,可以传函数以便回退到当前页面时带回下一个页面的数据。
- pop
this.pop();
参数传递回上一个页面:pop 前调用上个页面 push 时参数里面传的回调函数。
导航栏
目前对RN原生做了简单封装,在每个页面可以自由配置:
this.props.page.title = '标题栏';
this.pros.page.rightButton = (
<
View
>
...
<
/View
>
);
note:CRN 对原生的 android 导航栏做了改动,高度改成了携程导航栏同一高度(50 point),颜色默认改成了携程蓝色。
返回按钮
默认返回按钮有携程箭头,绑定了 navigation pop事件。
也可以自行处理返回事件,只要重写 pop 方法即可:
pop() {
// do something.
super.pop();
}
修改 HellorWorld
了解了这么多了,来体验下CRN的开发模式吧
打开HelloWorld目录
默认您已经安装了Atom
➜ Desktop open HelloWorld -a Atom
打开的效果图:
找出 HelloWorld 的 bug
src
目录下有page1
,page2
两个页面,但是page1
如何跳转到page2
呢?
群众甲:'应该是有个按钮,点击之后跳转到page2
'
群众乙:'爱卿所言甚是,但是页面上的按钮呢?'
群众丙:'。。。找到了,按钮标题是白色,跟背景色反差太小了'
都说群众的眼睛是雪亮的,bug被找到了:
现在开始您CRN开发的第一步,给按钮设置个背景色
在Atom中找到
HelloWorld
的src
中的page1
定位到45行
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
button: {
}
});
给button添加背景色
button: {
backgroundColor:'black'
}
- 预览修改后的效果
代码修改后,是不是重新crn-cli run-ios
走一遍之前的流程?
不需要
不需要
不需要
接下来见证奇迹的时刻:选中模拟器,然后cmd + r
,模拟器上的页面神奇的刷新了~~
随时预览这也是RN的魅力之一