(三)react-native开发系列之开发环境集成

先上图,由于是虚拟机中的ios虚拟器,所以有点卡

关于react-native的开发集成,主要包括以下几个方面

1、路由及页面跳转

2、数据请求的封装

3、状态的管理

4、公共方法和全局变量的封装

5、页面的响应式适配

接下来就围绕这几个主要功能,来谈下这次项目重构中我的项目集成目录,项目的基本架构放在了github上面,下面的内容都对应这个项目目录来写,可以拉取代码到本地跑起来对应下面内容看起来更方便。

1、路由及页面跳转

页面的跳转是整个项目最基础的部分,如果页面无法跳转的话,项目也跑不起来了;看了react-navigation和Navigator,不知道为什么,感觉Navigator上手比较简单一些,虽说官方推荐使用react-navigation,但我还是选择了Navigator,谁让我看它顺眼呢,接下来引入Navigator。

这里说下,如果直接import {Navigator} from "react-native"这样引入的话是会报错的,查看官方说明,已经将Navigator单独放进react-native-deprecated-custom-components里面了,所以要想使用Navigator要先下载react-native-deprecated-custom-components,使用如下命令

npm install react-native-deprecated-custom-components --save

新建Component/Main目录,在此目录下新建navigatorcot.js,在App.js里引入此文件,用于配置路由和tab切换

在navigatorcot.js里引入Navigator

import React, { Component } from 'react';
import { Navigator } from 'react-native-deprecated-custom-components'    // 引入路由
import tabcomponent from "./tabbar"
export default class Navigatorcot extends Component {
  render(){
    return(
      <Navigator
        style={{flex:1}}     // 样式
        initialRoute={{ name: 'tabcomponent', component: tabcomponent }}    // 初始化路由
        configureScene={() => {// 过渡动画
          return Navigator.SceneConfigs.PushFromRight;
        }}
        renderScene={(route, navigator) => {
          let Component = route.component;
          return <Component {...route.passProps} navigator={navigator} />;   // 全局路由参数和路由
        }}
      />
    )
  }
}

上面是路由跳转的配置,动画使用的PushFromRight,tab的话是使用的react-native-tab-navigator,这里为了避免从tab页跳转到详情也的时候,底部tab依然存在的情况,采用了将tabcomponent放入initialRouter里,下面是tabcomponent的代码,在navigatorcot.js的同级目录下,新建tabbar.js

首先下载react-native-tab-navigator依赖

npm install react-native-tab-navigator --save

配置底部tab,这里以主页tab为例,引入Home组件,其它组件一样引入

import TabNavigator from 'react-native-tab-navigator';  // 引入tab组件
import Home from "../Home/homeindex";  // 主页组件

render() {
    return (
      <TabNavigator>
        <TabNavigator.Item
          title='主页'
          onPress={() => { this.setState({ selectedTab: 'home' }); DeviceEventEmitter.emit('userNameDidChange', '1') }}
          selected={this.state.selectedTab === 'home'}
          renderIcon={() => <Image source={require('../../assets/img/index-noselect.png')} style={styles.iconStyle} />}
          selectedTitleStyle={styles.selectedTitleStyle}
          renderSelectedIcon={() => <Image source={require('../../assets/img/index-select.png')} style={styles.iconStyle} />}
        >
          <Home navigator={this.props.navigator} />   // 将navigator传如子组件
        </TabNavigator.Item>
      </TabNavigator>
   )
}

2、请求的封装

新建Component/Global目录,这个目录用于存放一些全局变量,和定义的公共方法,在此文件夹下面新建fetch.js,封装代码如下

/**
 * 封装请求方法
 */
let baseurl = ""
export function fetchData(url, params) {
    url = `${baseurl }${url}`;
    params = {
        body: params
    }
    return new Promise(function (resolve, reject) {
        fetch(url, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json;charset=UTF-8',
                'Authorization': TOKEN     // 定义在全局变量里
            },
            body: JSON.stringify(params),   //body参数,通常需要转换成字符串后服务器才能解析
        }).then((response) => response.json())
            .then((responseData) => {
                console.log('res:', url, responseData);   //网络请求成功返回的数据
                resolve(responseData);
            })
            .catch((err) => {
                console.log('err:', url, err);   //网络请求失败返回的数据  
                reject(err);
            });
    });

}

调用此方法,只需要调用fetchData函数,传入对应的请求地址和请求参数即可,这里以登录为例

新建Component/Api目录,新建commonapi.js用于定义调用的接口,代码如下

/**
 * created by Mr.Gao
 * 通用api统一调用
 */
import { fetchData } from "../Global/fetch";

// 登录
export function loginIn(params) {
    return fetchData(`/root/login/checkMemberLogin`, params)
}

页面登录调用如下

import * as commonApi from '../Api/commonapi';  // 引入commonApi

let params = {
  password: this.state.password,
  userName: this.state.user
}
commonApi.loginIn(params).then(data => {
   if (data.success === ERROR_OK) { // ERROR_OK全局调用成功状态
     alert(data.message);
   } else {
     alert(data.message);
   }
}).catch((res) => {
  alert(res)  // 接口调用失败
})

3、状态管理的引入

这里使用redux作为状态管理工具,安装react-redux、redux、redux-logger

npm install react-redux redux redux-logger --save

新建Component/Redux目录,如下图

在App.js里引入store并注册,如下代码

  import { Provider } from 'react-redux';  
  import store from './Component/Redux/store';

  render() {
    return (
      <Provider store={store}>
          <Main />
      </Provider>
    );
  }

下面以在Mine/mineindex.js里调用加减数为例

import { increase } from '../Redux/actions';  // 导入加方法

this.props.dispatch(increase(10));  // 每次加10

<Text>{this.props.counter.count}</Text>  // 获取状态数据

const mapStateToProps = state => ({  // 在组件底部使状态生效
  counter: state.counter
})

export default connect(mapStateToProps)(Mine);

4、公共方法和全局变量的封装

有的时候项目多个部分需要调取同一个方法,再如稍后提到的页面适配的公共方法以及想用的全局变量,需要找一个公共的方法存放,这里使用全局变量global,如下图

index.js里定义了一些基础字号和全局主题颜色,tools.js封装了本地存储及设备适配等方法,以index.js为例

// 请求全局状态
global.ERROR_OK = true;
// 系统是iOS
global.iOS = (Platform.OS === 'ios');
// 系统是安卓
global.Android = (Platform.OS === 'android');
// 获取屏幕宽度
global.SCREEN_WIDTH = width;
// 获取屏幕高度
global.SCREEN_HEIGHT = height;
// 获取屏幕分辨率
global.PixelRatio = PixelRatio.get();
// 最小线宽
global.pixel = 1 / PixelRatio;
// 适配字体
global.FONT_SIZE = FontSize;
// 屏幕适配
global.px2dp = px2dp;
// 全局存储
global.storage = storage;
// 全局字体颜色
global.fontcolor = "#474a4f";
// 全局背景色
global.bgcolor = "#F0F0F0";

在App.js里引入index.js,使index.js起作用就可以在项目中任何地方调用了

import "./Component/Global/index"

5、页面的适配

这两个文件里分别定义了FontSize和px2dp方法,分别用来适配字体大小和适配距离

代码很简单,就不贴出来了,可以去项目文件里看一下。

由于是一个人开发,项目中的各个配置难免有缺陷,目前也没有高人指点,如有大神看到有需要改进的地方还请指教。

 

转载于:https://www.cnblogs.com/gaosong-shuhong/p/9645501.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值