JNUfeatherwit / blog

6 stars 0 forks source link

ReactNative之react-navigation+ mobx+antd 基本框架搭建 #1

Open JNUfeatherwit opened 6 years ago

JNUfeatherwit commented 6 years ago

框架介绍

react-navigation

rn的一个管理路由、页面切换的框架

mobx

管理异步数据的框架,实现观察者模式的理念,将异步数据统一管理起来,使数据实现自动更新

antd

淘宝开发的rn和react的UI框架

环境配置文件

//package.json
{
  "name": "lyra",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start",
    "install-apk": "adb install -r ./android/app/build/outputs/apk/app-debug.apk",
    "debug-apk": "cd android && gradlew assembleDebug && npm run install-apk && npm run bind",
    "build:api": "node ./axios_service/codegen.js && tsc -p ./axios_service",
    "test": "jest"
  },
  "husky": {
    "hooks": {
      "pre-commit": "pretty-quick --staged"
    }
  },
  "dependencies": {
    "antd-mobile-rn": "^2.2.1",
    "axios": "^0.18.0",
    "camelcase": "^5.0.0",
    "jsc-android": "224109.x.x",
    "lodash": "^4.17.10",
    "mobx": "^5.0.3",
    "mobx-form-validator": "^1.3.2",
    "mobx-react": "^5.2.3",
    "prop-types": "^15.6.2",
    "react": "16.3.1",
    "react-native": "0.55.4",
    "react-native-storage": "^0.2.2",
    "react-native-vector-icons": "^5.0.0",
    "react-navigation": "^2.10.0"
  },
  "devDependencies": {
    "babel-eslint": "^8.2.6",
    "babel-jest": "23.4.2",
    "babel-plugin-import": "^1.8.0",
    "babel-plugin-module-resolver": "^3.1.1",
    "babel-plugin-transform-decorators-legacy": "^1.3.5",
    "babel-preset-react-native": "4.0.0",
    "eslint": "^5.2.0",
    "eslint-config-prettier": "^2.9.0",
    "eslint-import-resolver-babel-module": "^4.0.0",
    "eslint-plugin-import": "^2.13.0",
    "eslint-plugin-prettier": "^2.6.2",
    "eslint-plugin-react": "^7.10.0",
    "husky": "^1.0.0-rc.13",
    "jest": "23.4.2",
    "prettier": "^1.14.0",
    "pretty-quick": "^1.6.0",
    "react-test-renderer": "16.3.1",
    "swagger-axios-codegen": "^0.2.6"
  },
  "jest": {
    "preset": "react-native"
  }
}

重点模块解析

babel

新一代javascript语言的转换器,可将es6转换成es5,并配有支持各类型框架语言或写法的模块

babel-plugin-import

实现‘按需加载’的模块

依赖{ 编译fileTree(dir:“libs”,包括:[“* .jar”])

### lodash
JavaScript的一套工具库,内部封装了诸多对字符串、数组、对象等常见数据类型的处理函数
### mobx-form-validator
mobx的一个form表单自动校验的框架
- 基本用法

class LoginForm { @observable @validator([ { required: true, message: '用户名不能为空' } ]) userName = ''

@observable @validator([ { required: true, message: '密码不能为空' } ]) password = '' } const form = new RegisterForm(); console.log(form.validateErrorUserName); // 用户名不能为空 console.log(form.validateErrorPassword); //密码不能为空 console.log(form.isValid); // false

### react-native-storage
是本地持久存储的封装,可以同时支持react-native(AsyncStorage)和浏览器(localStorage)
### script下的字段
都可以用yarn name或npm run name运行
# 基本架构
### 整体概况
- 整体目录
![](https://github.com/164275563/blog/blob/master/images/directorys.PNG?raw=true)
- src目录
![](https://github.com/164275563/blog/blob/master/images/src.PNG?raw=true)
### 基本配置
> app.js

import boot from './src/boot/index' const app = boot() export default app

> boot/index.js

import { configure } from 'mobx'

import config from './configureStore' import app from './setup' // 全局配置文件 import 'utils/storage' import 'utils/axiosConfig'

export default function() { const stores = config() configure({ enforceActions: true }) // 进入严格模式,不允许通过action之外的方式改变observable属性 return app(stores) }

> boot/configureStore.js

import AppStore from '../store/AppStore'

export default function() { const appStore = new AppStore() return { appStore } }

> boot/setup.js

import * as React from 'react' import { Provider } from 'mobx-react/native'

import App from '../App'

export interface Props {} export interface State {}

export default function(stores) { return class Setup extends React.Component<Props, State> { render() { return ( <Provider {...stores}>

    </Provider>
  )
}

} }

> src/app.js

import React from 'react' import { createStackNavigator, createSwitchNavigator } from 'react-navigation' import { NavigationService } from 'utils' import SplashScreen from './screens/Splash' import HomeScreen from './screens/Home' import LoginScreen from './screens/Login' import type { Props } from './boot/setup' import FrontScreen from './screens/Front' import ElMeterScreen from './screens/ElMeter' import MessageScreen from './screens/Message' import SettingScreen from './screens/Setting' import StackStyleInterpolator from 'react-navigation/src/views/StackView/StackViewStyleInterpolator.js'

const AppStack = createStackNavigator( { Home: HomeScreen, First: FrontScreen, ElMeter: ElMeterScreen, Message: MessageScreen, Setting: SettingScreen }, { headerMode: 'none', transitionConfig: () => ({ //设置横向切换动画 screenInterpolator: StackStyleInterpolator.forHorizontal }) } )

const RootStack = createSwitchNavigator( { Splash: SplashScreen, App: AppStack, Login: LoginScreen }, { initialRouteName: 'Splash' } )

export default class App extends React.Component { render() { return ( <RootStack ref={navigatorRef => { NavigationService.setTopLevelNavigator(navigatorRef) }} /> ) } }

> screens/Home/index.js

import React from 'react' import { createBottomTabNavigator } from 'react-navigation' import Icon from 'react-native-vector-icons/FontAwesome' import FirstScreen from '../Front' import ElMeterScreen from '../ElMeter' import MessageScreen from '../Message' import MineScreen from '../Mine' import { basicColor } from '../../theme/MainStyle'

const renderIcon = (name, tintColor) => <Icon name={name} size={22} style={{ color: tintColor }} />

const tabScreens = { first: { screen: FirstScreen, navigationOptions: { tabBarLabel: '首页', tabBarIcon: ({ tintColor }) => renderIcon('home', tintColor) } }, elMeter: { screen: ElMeterScreen, navigationOptions: { tabBarLabel: '电表', tabBarIcon: ({ tintColor }) => renderIcon('cube', tintColor) } }, message: { screen: MessageScreen, navigationOptions: { tabBarLabel: '消息', tabBarIcon: ({ tintColor }) => renderIcon('comments-o', tintColor) } }, mine: { screen: MineScreen, navigationOptions: { tabBarLabel: '我的', tabBarIcon: ({ tintColor }) => renderIcon('user', tintColor) } } } const tabConfig = { tabBarPosition: 'bottom', tabBarOptions: { inactiveTintColor: '#a0a0a0', activeTintColor: basicColor.mainColor, indicatorStyle: { backgroundColor: 'transparent' }, showIcon: true, style: { margin: 0, backgroundColor: '#ffffff', borderTopWidth: 0.66, borderTopColor: '#dddddd' }, tabStyle: { padding: 0, margin: 0 }, labelStyle: { fontSize: 11, margin: 0, marginBottom: 5 }, iconStyle: { marginTop: -3, marginBottom: 0 } }, swipeEnabled: false } const HomeTab = createBottomTabNavigator(tabScreens, tabConfig)

export default HomeTab

### babel配置
> .babelrc

{ "presets": ["module:metro-react-native-babel-preset"], "plugins": [ [ "module-resolver", { "cwd": "babelrc", "root": ["./src"], "alias": { "utils": "./src/utils" } } ], [ "import", { "libraryName": "antd-mobile-rn" } ], ["@babel/plugin-proposal-decorators", { "legacy": true }] ] }


### 代码格式化配置
> .eslintrc

// eslint { "root": true, "parser": "babel-eslint", // 使用babel解析器 // 加入各个环境的全局变量 "env": { "es6": true, "node": true, "jest": true }, "extends": [ "plugin:prettier/recommended", "plugin:import/errors", "plugin:import/warnings", "plugin:react/recommended", "eslint:recommended" ], "settings": { "import/resolver": { "babel-module": { "paths": ["src"] } } }, "rules": { "no-console": "off", // 是否允许使用console,eslint/recommended默认开启,这里把它关闭了 "react/prop-types": [1] // 要求组件指定proptypes },

// 自定义全局的变量(env里的环境不包括的) "globals": { } }

> .prettierrc

// prettier

{ "singleQuote": true, "printWidth": 120, "semi": false, "tabWidth": 2 }

>.package.json

// git的hook ... "husky": { "hooks": { "pre-commit": "pretty-quick --staged" //提交前进行一次prettier校验 } }, ...