01.基础-项目初始化

知识点:
1.快速创建RN项目
2.添加使用路由功能
3.不要在RN中使用的功能

从这里开始,我们将一步一步的创建一个可以真正的使用的app。第一部分讲述开发一个app的大致过程,第二部分将开始优化性能、开发效率等,第三部分教大家添加热更新、支付、分享这些功能。大多数第三方组件可以很方便的link到项目里,部分需要手动导入甚至主动开发一些东西,这里也会在用到的时候讲出来。

创建项目的前提条件·

使用react-native创建一个新的项目请确保你的电脑上已经满足下面的这些条件。

  • nodejs。RN的所有库都是从npm上安装的。请确保你的电脑上已经安装了npm。可以使用npm -v来查看当前是否安装了npm。当前项目使用的node版本是8.9.3,npm的版本是5.5.3。
  • react-native-cli。这个通常用作RN的初始化和启动模拟器等,是用npm可以安装到电脑上。
  • python。RN里面有些脚本是使用python写的。请确保电脑上已经安装了python2.7以上的版本。
  • jdk1.8。安卓项目需要使用jdk1.8,请在电脑上安装好jdk1.8。安装的教程可以方便从网上搜索到。
  • Android Studio。调试以及编译安卓代码需要使用到。请在安装Android Studio之后安装好Android SDK以及模拟器。模拟器可以使用市面上的安卓模拟器,它们普遍比自带的模拟器要快。闲麻烦的同学可以直接连接手机调试。在安装好IED之后请下载好需要使用到的androidSDK。下载SDK需要科学上网或者把下载地址替换成国内的几个下载源。
  • git。后面的项目会加入到git中,使用git做版本管理的好处不言而喻。
  • Xcode(仅ios项目中)。安装了Xcode才能使用iOS模拟器。ios模拟器下的开发速度要明显优于安卓下,后面的开发过程大多数也是在ios模拟器中进行的。在模拟器中的表现都差不多,有些不一样的效果可以在看到的时候单独调试。
  • Watchman(仅mac系统用到)。Watchman用来监听文件变动等。mac下必须安装Watchman。
  • vscode。文中演示项目使用的编辑器是vscode。这里也推荐使用vscode开发前端项目。

创建项目

我们先在本地创建一个可运行的项目,同时这个项目会加入到git的版本管理中。

  1. 执行react-native init anxintao --version 0.53.0
    enter image description here
    图中1代表之前安装的react-native-cli的命令。
    图中2代表初始化命令。
    图中3代表项目的名称,这里是anxintao
    图中4代表指定RN的版本号,这个参数不传默认使用最新版。
    图中5代表RN具体使用的版本号。

  2. 使用vscode打开项目,在项目根目录下执行命令启动初始化之后的项目,mac下推荐react-native run-ios,window下推荐react-native run-android启动默认的项目。如果能启动说明项目初始化完成,否则说明项目的某些东西没有安装好。
    enter image description here
    这里推荐把启动的命令写入到package.json文件中。比如:输入npm run ios即可代替原来的react-native run-ios,输入命令的速度快了不少。也可以给vscode安装一个启动RN的插件,不过效果跟输命令差不多,具体要看个人习惯了。

  3. 到这里就说明项目创建成功了。这个项目现在还很简单,它的原生部分只有一个简单的空壳。这个空壳仅仅是初始化了一个RN的activity,所有的js都是运行在根视图上的。

  4. 这里注意一下,新建的项目提示了按键可以刷新页面或者调出菜单。这显示的是ios模拟器,按键为command R刷新和command D调出菜单。

添加路由

一个完整的项目不能没有路由。这里我们使用React Navigation

在写文章的时候已经有一个路由组件react-native-navigation热度超过了react-navigation。它更多的使用的是原生的路由切换,效果更好。想用的同学可以去尝试一下。

  1. 安装路由。在根目录下执行npm install --save react-navigation
  2. 在根目录下新建src目录。所有页面放入这个文件夹下。
  3. 新建一个首页,给后面的路由调用。页面路径为:根目录/src/home/index.js

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    'use strict';

    import React from 'react';
    import {
    StyleSheet,
    View,
    Text
    } from 'react-native';

    export default class extends React.Component {
    render() {
    return <View style={{ marginTop: 200 }}>
    <Text>这是首页</Text>
    </View>
    }
    }
  4. 修改根目录下的index.js。添加整个项目的路由。

    1
    2
    3
    4
    import { AppRegistry } from 'react-native';
    import Pages from './src';
    //启动
    AppRegistry.registerComponent('anxintao', () => Pages);

    5.在src目录下新建index.js文件。在这个文件里添加路由。我们从简单的一个页面开始。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    'use strict';

    import React from 'react';
    import {
    StyleSheet
    } from 'react-native';
    //添加路由组件
    import Navigation from 'react-navigation';

    //添加展示用的首页
    import Home from './home/index'

    //创建路由
    const Pages = Navigation.StackNavigator({
    'Home': {
    screen: Home
    }
    }, {
    //这里做了一个页面跳转的动画
    transitionConfig: () => ({
    screenInterpolator: sceneProps => {
    const { layout, position, scene } = sceneProps;
    const { index } = scene;
    //设置页面跳转的动画
    const translateX = position.interpolate({
    inputRange: [index - 1, index, index + 1],
    outputRange: [layout.initWidth, 0, 0]
    });
    const opacity = position.interpolate({
    inputRange: [index - 1, index - 0.99, index, index + 0.99, index + 1],
    outputRange: [0, 1, 1, 0.3, 0]
    });
    return { opacity, transform: [{ translateX }] };
    }
    }),
    navigationOptions: {
    header: null
    }
    });

    //创建一个自己的容器,方便以后对路由做一些处理
    export default class extends React.Component{
    constructor(props) {
    super(props);
    }

    render() {
    return <Pages onNavigationStateChange={this.listenChange.bind(this)}></Pages>;
    }
    //监听路由的跳转
    listenChange(state1, state2, action) {

    }
    }

6.添加完成之后删除掉初始化项目之后的App.js。这个时候在模拟器中使用快捷键command+R即可刷新刷新页面。
enter image description here
7.至此就完成了简单的路由设置。之后只需要添加页面并在路由中注册即可使用。

路由升级版

简单的路由并不能起到很好的作用,我们还是创建一个更实用的路由吧。比如带3个tab切换的首页,这也是大多数app使用套路。

  1. 添加4个tab切换页。我们假定未来需要4个切换页,分别是首页、分类页、购物车、个人中心。在home下分别创建他们。
    enter image description here
  2. 修改路由所在的index文件。引入下面要用到的几个组件和页面

添加新加入的页面

1
2
3
4
5
6
7
8
9
10
11
12
import React from 'react';
import {
StyleSheet,
Image
} from 'react-native';
//添加路由组件
import Navigation from 'react-navigation';
//添加展示用的首页
import Home from './home/index'
import Products from './home/products'
import Shop_Cart from './home/shop_cart'
import My from './home/my'

创建底部的样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//创建tab页的顶部样式
const styles = StyleSheet.create({
tab: {
height: 40,
backgroundColor: '#fbfafc',
borderTopColor: '#efefef'
},
tabIcon: {
width: 20,
height: 20
},
tabLabel: {
marginBottom: 4
}
})

创建一个tab路由,为了简单这里只展示2个页面的。具体的代码可以去git仓库查看。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

//创建首页的tab页
const Tabs = Navigation.TabNavigator({
'Home': {
screen: Home,
navigationOptions: ({ navigation, screenProps }) => {
return {
tabBarLabel: '首页',
tabBarIcon: (opt) => {
if (opt.focused) return <Image source={{ uri: require('./images/tab-home-active') }} style={styles.tabIcon}></Image>;
return <Image source={{ uri: require('./images/tab-home') }} style={styles.tabIcon}></Image>;
}
}
}
},
'Products': {
screen: Products,
navigationOptions: ({ navigation, screenProps }) => {
return {
tabBarLabel: '产品分类',
tabBarIcon: (opt) => {
if (opt.focused) return <Image source={{ uri: require('./images/tab-products-active') }} style={styles.tabIcon}></Image>;
return <Image source={{ uri: require('./images/tab-products') }} style={styles.tabIcon}></Image>;
}
}
}
},
}, {
//设置tab使用的组件
tabBarComponent: Navigation.TabBarBottom,
//点击哪个才加载哪个tab里的页面
lazy: true,
//设置tab放在界面的底部
tabBarPosition: 'bottom',
//设置tab里面的样式
tabBarOptions: {
style: styles.tab,
labelStyle: styles.tabLabel,
activeTintColor: '#d0648f'
}
});

替换Pages里的第一个页面为刚才创建的Tab路由。由于默认加载第一个,所以需要将第一个设置成tab页。

1
2
3
'Tabs': {
screen: Tabs
}

3.现在再刷新模拟器,就会发现底部的Tab切换已经好了。点击可以切换不同的页面。
enter image description here

4.这里我将图片转化成base64的方式再引入到图片组件中。好处是打包之后会变成一个整体。坏处是打包之后的bundle文件会变大,做增量更新也比较麻烦。

不推荐使用的东西

  1. 投影。安卓不支持投影,在开发的时候如果没有必要就使用别的方式代替吧。比如使用图片代替投影。
  2. 边框色。在长列表中尽量不要使用边框色,在某些安卓手机下会闪退。
  3. 使用了圆角的情况再使用背景色。ios手机会出现边框颜色异常或者异常色块。去掉背景即可。
  4. 过于深层次的结构
  5. 过于频繁的刷新state
请支持我一下吧.