[email protected] 使用 Typescript 擼一個APP

激動不已 ~
自從 [email protected] 版本之後,進入了內網編程。在一個封閉的小圈圈裏,以 [email protected] 版本進行編程。全靠徒手手擼 代碼 ,總覺得大能量無處盡放 !
今天決定使用疫情期間學習的Typescript語言,來實現一個 [email protected] 版本的移動APP
項目使用Typescript語言,集成了路由 導航react-navigation 和 react-native-material-tabs。分別實現了 登錄頁、庫存列表頁和庫存單品詳情頁 3個頁面。
先附帶一下自己用Photoshop繪製的效果圖**😗*
在這裏插入圖片描述
接下來,配置具備Typescript語言編程環境的 [email protected] 的項目。
介紹一個具備ts語言的RN模板,指令即可完成項目初始化
在這裏插入圖片描述
新建一個目錄,在dos窗口執行終端命令 npx react-native init CarglassApp --template react-native-template-typescript

執行過程中,你或許會遇到這個 error error An unexpected error occurred: "https://registry.npm.taobao.org/react-native-template-react-native-template-typescript: Not found".

不捉急,有解決方案:

remove legacy react-native-cli
npm uninstall -g react-native-cli

install new thing
npm i -g @react-native-community/cli

and you can new project with react-native-template-typescript
npx react-native init MyApp --template react-native-template-typescript

然後你會發現,it works .
而報錯原因是因爲我在 react-native 官網搭建環境裏配置所導致的資源路徑不對。通過以上 的修改則it works .

# 使用nrm工具切換淘寶源
npx nrm use taobao

# 如果之後需要切換回官方源可使用 
npx nrm use npm

CarglassAPP 項目初始化成功之後,讓工程在安卓模擬器中跑起來。執行命令 cd CarglassApp && yarn react-native run-android
初始化工程
在這裏插入圖片描述
yarn react-native run-android 運行成功
在這裏插入圖片描述
效果展示
在這裏插入圖片描述
至此具備 Typescript 語言配置的 react-native 工程就配置完成了。
在這裏插入圖片描述
由於 RN 高版本的更新導致,安卓模擬器設備無法通過快捷鍵彈出調試菜單。但是可以在終端使用指令彈出調試菜單 adb shell input keyevent 82

經過一天的編碼,展示一下成果圖:

在這裏插入圖片描述
在該Demo項目中,使用到了Typescript語言下配置的路由導航react-navigation。
在這裏插入圖片描述
程序編寫過程中在路由導航時,遇到了很多問題。在Typescript的路由配置難度上要高於Javascript。回顧一下解決該問題的過程,在Google上搜到了一篇文章並結合react-avigation官網。對於編寫完好的程序,在
import {createAppContainer , createStackNavigator} from "react-navigation"; 的lib屬性 createStackNavigator上代碼檢查報錯。
然後強制執行yarn react-native run-andorid命令之後,看到報錯具體內容
在這裏插入圖片描述
緊接着根據提示安裝引用庫,yarn add react-navigation-stack 之後又有很多報錯,缺少這個庫缺少那個庫,react-native 命令不存在等等!

最終解決方案就是 提示缺少什麼就裝什麼
大概需要安裝的lib有(如有不足請繼續安裝):yarn add react-native react-native-gesture-handler react-native-safe-area-context react-native-screens react-navigation react-navigation-stack
還有部分對應的類型聲明(如有不足請繼續安裝): yarn add @react-native-community/masked-view @react-navigation/native @react-navigation/stack @types/react @types/react-navigation
源碼附贈展示,點擊下載查看

package.json 的配置文件上的版本內容

react-native react-navigation @types/react-navigation typescript 省略…
^0.61.5 ^4.2.2 ^3.4.0 3.7.3 省略…

成功運行之後的效果源碼:

//APPEntrance.tsx
import React from 'react';
import {
  AppRegistry,
  Text,
  TouchableOpacity
} from 'react-native';
import AppContainer from './src/screens/AppContainer';

export default class HomeScreen extends React.Component {

  render() {
    return <AppContainer />
  }
}

//APPContainer.tsx
import React, { Component } from 'react';
import {
  SafeAreaView,
  StyleSheet,
  View,
  Text,
  StatusBar,
  Image,
  Dimensions,
  ImageSourcePropType,
  ScaledSize,
  FlatList,
  TextInput
} from 'react-native';
import RespoList from './RespoList';
import {createAppContainer } from "react-navigation";
import { createStackNavigator, NavigationStackScreenProps } from 'react-navigation-stack';
import { TouchableOpacity } from 'react-native-gesture-handler';
import DeviceConfs from '../confs/DeviceConfs';
import ImgConfs from '../../src/confs/ImgConfs';

type AppProps = NavigationStackScreenProps;
class AppContainer extends React.Component<AppProps> {
  static navigationOptions = {
    title: '',
  };
 

  render(): React.ReactNode {
      return (<View style={{backgroundColor: '#418dfb', flex: 1, alignItems: 'center'}}>
        

        <Image source={ImgConfs.icon_logo_word} resizeMode={'contain'} 
              style={{width: 120, height: 80, marginTop: 80}}/>

        <TextInput 
          style={{ height: 42, borderColor: '#6a6a6a', borderWidth: 1, borderRadius:4, marginTop:50,
            backgroundColor:'white', width: DeviceConfs.sWidth * 0.75 , paddingHorizontal: 12}}
            placeholder={'用戶名/手機號'}  placeholderTextColor={'rgba(146,146,146,0.6)'}/>
        <TextInput 
          style={{ height: 42, borderColor: '#6a6a6a', borderWidth: 1, borderRadius:4, marginTop:20,
            backgroundColor:'white', width: DeviceConfs.sWidth * 0.75 , paddingHorizontal: 12}}
            placeholder={'密碼'}  placeholderTextColor={'rgba(146,146,146,0.6)'}/>
            

        <TouchableOpacity activeOpacity = {0.8}
                    style={{borderColor:'white', borderWidth:1, backgroundColor:'white', borderRadius: 6,marginTop: 100,
                          width:DeviceConfs.sWidth * 0.75, height:42, justifyContent: 'center', alignItems:'center'}} 
        onPress={()=>{this.props.navigation.navigate('RespoList')}}>
        <Text style={{color:'#418dfb', fontSize: 16, fontWeight:'bold'}}>{'立即登錄'}</Text>
      </TouchableOpacity>


      <Image source={ImgConfs.bg_logo1} resizeMode={'contain'} 
              style={{width: 120, height: 80, position:'absolute', top: DeviceConfs.sHeight * 0.35, left: 15}}/>
      <Image source={ImgConfs.bg_logo2} resizeMode={'contain'} 
              style={{width: 120, height: 80, position:'absolute', top: DeviceConfs.sHeight * 0.28, left: DeviceConfs.sWidth * 0.6}}/>
      <Image source={ImgConfs.bg_logo3} resizeMode={'contain'} 
              style={{width: 120, height: 80, position:'absolute', top: DeviceConfs.sHeight * 0.75, left: DeviceConfs.sWidth * 0.4}}/>
      </View> );
  }

}

const AppNavigator = createStackNavigator({
  AppContainer: { screen: AppContainer },
  RespoList: { screen: RespoList }
}, {
  defaultNavigationOptions:{
    header: null
}
});

export default createAppContainer(AppNavigator);
//RespoList.tsx
import React, { Component } from 'react';
import {
  SafeAreaView,
  StyleSheet,
  View,
  Text,
  StatusBar,
  Image,
  Dimensions,
  ImageSourcePropType,
  ScaledSize,
  FlatList,
  ScrollView
} from 'react-native';
import {ResItem} from '../interfaces/Types-list';
import RespertoryItem from '../components/RespertoryItem';

import {
  Header,
  LearnMoreLinks,
  Colors,
  DebugInstructions,
  ReloadInstructions,
} from 'react-native/Libraries/NewAppScreen';
import DeviceConfs from '../confs/DeviceConfs';
import ImgConfs from '../confs/ImgConfs';
import PageFlip from '../components/PageFlip';
import listJson from './list-json';
import { TouchableOpacity } from 'react-native-gesture-handler';

type RespoListProps = any;

class RespoList extends Component<RespoListProps>{

  constructor(props: RespoListProps){
    super(props);
  }

  render(){

    return (
    <View style={styles.engine}>
      
        <View style={{width: DeviceConfs.sWidth, height: 42, 
            flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between'}}>
            <TouchableOpacity onPress={()=>{this.props.navigation.pop()}} activeOpacity = {0.8}
              style={{flexDirection:'row', alignItems: 'center', width:DeviceConfs.sWidth * 0.3}}>
              <Image source={ImgConfs.ic_goback} resizeMode={'contain'} 
              style={{width: 38, height: 38}}/>
              <Text style={{color: '#444', fontWeight: 'bold', fontSize: 14, alignSelf: 'center', marginLeft: -6}}>{'返回'}</Text>
            </TouchableOpacity>
          <View style={{width:DeviceConfs.sWidth * 0.3, alignItems: 'center', justifyContent:'center'}}>
            <Text style={{color: '#333', fontWeight: 'bold', fontSize: 18}}>{'庫存列表'}</Text>
          </View>
          <View style={{width:DeviceConfs.sWidth * 0.3}}/>
        </View>
        <View style={{height:4, width: DeviceConfs.sWidth, backgroundColor: '#f4f4f4'}}/>

        <PageFlip onPreClick={()=>{}}  onNextClick={()=>{}} />
        <View style={{height:4, width: DeviceConfs.sWidth, backgroundColor: '#f4f4f4'}}/>
        
        <FlatList
          ref="flatList"
          style={{flex:1}}
          data={listJson}
          showsVerticalScrollIndicator={false}
          ItemSeparatorComponent={this.separatorComponent} // 分割線
          extraData={this.state}
          keyExtractor={this._keyExtractor}
          renderItem={({item})=>this.renderItem(item)}
        />

<View style={{width: DeviceConfs.sWidth, height: 60, 
                backgroundColor: '#aa9a9a9a', position: 'absolute', left:0, top: DeviceConfs.sHeight - 80,
                alignItems:'center',  justifyContent: 'space-around', flexDirection: 'row'}}>
            <TouchableOpacity style={{width: DeviceConfs.sWidth * 0.3, height: 42, borderRadius:4,
                backgroundColor: '#16c36b', 
                alignItems:'center',  justifyContent: 'center', flexDirection: 'row'}}>
                  <Text style={{color: 'white', fontWeight: 'bold', fontSize: 16}}>{'入 庫'}</Text>
                </TouchableOpacity>
            <TouchableOpacity style={{width: DeviceConfs.sWidth * 0.3, height: 42, borderRadius:4,
                backgroundColor: '#ff5558', 
                alignItems:'center',  justifyContent: 'center', flexDirection: 'row'}}>
                  <Text style={{color: 'white', fontWeight: 'bold', fontSize: 16}}>{'出 庫'}</Text>
                </TouchableOpacity>
        </View>
    </View>)
  }

  _keyExtractor = (item: ResItem, index: number) => String(index)
  renderItem = (item: ResItem)=>{return <RespertoryItem {...item}/>}
  separatorComponent(){
    return <View style={{height: 1, backgroundColor: '#f4f4f4'}}/>
}
}
export default RespoList;

const styles = StyleSheet.create({

  engine: {
  flex:1,
  alignItems:'center',
  backgroundColor: 'white'
  }
  });
//Types-list.ts
type ImageRequireSource = number;
export interface ResItem {
  carIcon: ImageRequireSource;
  carSoldIcon : string;
  carName : string;
  frontGlass : string;
  behindGlass : string;
  isSold : boolean;
  isLast : boolean;
}



文章參考:
https://medium.com/@vnbnews.vn/reactnative-react-navigation-error
https://www.jianshu.com/p/618e644f6734

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章