【React Native 实战:构建电商 App】02-项目初始化

React Native 实战:构建电商 App

知识点:

  • 快速创建 RN 项目
  • 添加使用路由功能
  • 不要在 RN 中使用的功能

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

创建项目的前提条件

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

  • nodejs:RN 的所有库都是从 NPM 上安装的,请确保电脑上已经安装了 NPM,可以使用npm -v来查看当前是否已安装,当前项目使用的 Node 版本是 8.9.3,NPM 的版本是 5.5.3。
  • react-native-cli:这个通常用作 RN 的初始化和启动模拟器等,使用 NPM 可以安装到电脑上。
  • Python:RN 里面有些脚本是使用 Python 写的,请确保电脑上已经安装了 Python 2.7 以上的版本。
  • JDK 1.8:安卓项目需要使用 JDK 1.8,请在电脑上安装好,安装的教程可以搜索其他资料。
  • Android Studio:调试以及编译安卓代码需要使用到,请在安装 Android Studio 之后安装好 Android SDK 以及模拟器,模拟器可以使用市面上的安卓模拟器,它们普遍比自带的模拟器要快,闲麻烦的读者可以直接连接手机调试。在安装好 IED 之后请下载好需要使用到的 Android SDK,下载 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,它更多的使用的是原生的路由切换,效果更好,想用的读者可以去尝试一下。

  • 安装路由,在根目录下执行npm install --save react-navigation
  • 在根目录下新建src目录,所有页面放入这个文件夹下。
  • 新建一个首页,给后面的路由调用,页面路径为根目录/src/home/index.js
    '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>
        }
    }
    

修改根目录下的index.js,添加整个项目的路由。

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

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

'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) {

    }
}

添加完成之后删除掉初始化项目之后的 App.js,这个时候在模拟器中使用快捷键command+R即可刷新刷新页面。

至此就完成了简单的路由设置,之后只需要添加页面并在路由中注册即可使用。

路由升级版

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

添加 4 个 tab 切换页,我们假定未来需要 4 个切换页,分别是首页、分类页、购物车、个人中心,在 home 下分别创建他们。

修改路由所在的 index 文件,引入下面要用到的几个组件和页面。

添加新加入的页面:

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'

创建底部的样式:

//创建tab页的顶部样式
const styles = StyleSheet.create({
    tab: {
        height: 40,
        backgroundColor: '#fbfafc',
        borderTopColor: '#efefef'
    },
    tabIcon: {
        width: 20,
        height: 20
    },
    tabLabel: {
        marginBottom: 4
    }
})

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

//创建首页的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 页。

'Tabs': {
        screen: Tabs
 }

现在再刷新模拟器,就会发现底部的 tab 切换已经好了,点击可以切换不同的页面。

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

不推荐使用的东西

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

发表评论