{//********************************* React Native(前端) ***************************** Learn once , Write anywhere
官網: http://facebook.github.io/react-native/docs/getting-started.html
資源彙總: https://github.com/reactnativecn/react-native-guidehtml
JSX //js+xml -- js中嵌入html --> 避免js html的割裂(頻繁查找dom元素),實現真正的組件化
虛擬DOM //虛擬DOM和diff算法提升渲染性能 --> 提高性能前端
{//=====================================環境安裝============================ react
{//-----------------------------------本地開發調試---------------------- win10
{//安裝Android
1. 安裝Android (見前面H5跨平臺)
2. 設置環境變量 (win10 控制面板 -> 系統 -> 高級系統設置 -> 環境變量 -> 用戶變量裏點新建
新建ANDROID_HOME變量 C:\Users\ivan\AppData\Local\Android\sdk
在PATH變量裏新建 C:\Users\ivan\AppData\Local\Android\sdk\tools
在PATH變量裏新建 C:\Users\ivan\AppData\Local\Android\sdk\platform-tools
3.從新打開命令提示符,測試是否OK
> adb version //測試 成功會顯示adb版本
> android //測試 成功會打開Android SDK Manager 表示環境變量設置成功
}
npm install -g react-native-cli //install react native
react-native init AwesomeProject
cd AwesomeProject
經過usb線鏈接Android手機
react-native run-android /*成功會在手機上看到 Welcome to React Native
報錯: 一直在下載 gradle-2.4-all.zip
解決方法: 把咱們已下好的離線包gradle-2.4-all.zip放在對應目錄,
如C:\Users\ivan\.gradle\wrapper\dists\gradle-2.4-all\6r4uqcc6ovnq6ac6s0txzcpc0
報錯: build-tools 23.0.2
在http://mirrors.neusoft.edu.cn/android/repository/下載build-tools_r23.0.2-windows.zip後,
放在C:\Users\ivan\AppData\Local\Android\sdk\build-tools目錄下,並解壓
報錯: > Could not find com.android.support:support-v4:23.2.1.
解決方法:
在Android SDK Manager 下載 Extra裏Android Support 到最新
成功後能找到下面的目錄
C:\Users\ivan\AppData\Local\Android\sdk\extras\android\m2repository\com\android\support\support-v4\23.2.1
報錯:react native Unable to install app-debug.apk
解決方法:
更改 AwesomeProject\android\build.gradlel裏的版本爲1.2.3
*/
方式一: 手機直接連筆記本電腦wifi
Android手機wifi聯通電腦 /*
電腦 cmd 進入命令端
> netsh wlan set hostednetwork mode=allow ssid=glm key=00000000
> netsh wlan start hostednetwork
手機 wifi連接name 密碼 00000000
*/
更改 AwesomeProject/index.android.js裏的內容
react-native run-android //運行,會看到手機顯示內容有變化,表示環境ok
方式二:經過無線路由鏈接電腦
搖動手機 //會看到彈出的提示列表
選擇Dev Setttings
選擇Debug server host & port for device //設置IP地址如 192.168.1.5:8081 (需和電腦網卡ip一致,且手機和電腦在同一局域網)
回到Welcome界面
}
{//------------------------------------Webstorm------------------------- 源碼編輯軟件IDE(替代 Nuclide (React Native 默認IDE),因它不支持window)
安裝版本 WebStorm-2016.3.2.exe
破解碼activation code://43B4A73YYJ-eyJsaWNlbnNlSWQiOiI0M0I0QTczWVlKIiwibGljZW5zZWVOYW1lIjoibGFuIHl1IiwiYXNzaWduZWVOYW1lIjoiIiwiYXNzaWduZWVFbWFpbCI6IiIsImxpY2Vuc2VSZXN0cmljdGlvbiI6IkZvciBlZHVjYXRpb25hbCB1c2Ugb25seSIsImNoZWNrQ29uY3VycmVudFVzZSI6ZmFsc2UsInByb2R1Y3RzIjpbeyJjb2RlIjoiSUkiLCJwYWlkVXBUbyI6IjIwMTctMDItMjUifSx7ImNvZGUiOiJBQyIsInBhaWRVcFRvIjoiMjAxNy0wMi0yNSJ9LHsiY29kZSI6IkRQTiIsInBhaWRVcFRvIjoiMjAxNy0wMi0yNSJ9LHsiY29kZSI6IlBTIiwicGFpZFVwVG8iOiIyMDE3LTAyLTI1In0seyJjb2RlIjoiRE0iLCJwYWlkVXBUbyI6IjIwMTctMDItMjUifSx7ImNvZGUiOiJDTCIsInBhaWRVcFRvIjoiMjAxNy0wMi0yNSJ9LHsiY29kZSI6IlJTMCIsInBhaWRVcFRvIjoiMjAxNy0wMi0yNSJ9LHsiY29kZSI6IlJDIiwicGFpZFVwVG8iOiIyMDE3LTAyLTI1In0seyJjb2RlIjoiUEMiLCJwYWlkVXBUbyI6IjIwMTctMDItMjUifSx7ImNvZGUiOiJSTSIsInBhaWRVcFRvIjoiMjAxNy0wMi0yNSJ9LHsiY29kZSI6IldTIiwicGFpZFVwVG8iOiIyMDE3LTAyLTI1In0seyJjb2RlIjoiREIiLCJwYWlkVXBUbyI6IjIwMTctMDItMjUifSx7ImNvZGUiOiJEQyIsInBhaWRVcFRvIjoiMjAxNy0wMi0yNSJ9XSwiaGFzaCI6IjMzOTgyOTkvMCIsImdyYWNlUGVyaW9kRGF5cyI6MCwiYXV0b1Byb2xvbmdhdGVkIjpmYWxzZSwiaXNBdXRvUHJvbG9uZ2F0ZWQiOmZhbHNlfQ==-keaxIkRgXPKE4BR/ZTs7s7UkP92LBxRe57HvWamu1EHVXTcV1B4f/KNQIrpOpN6dgpjig5eMVMPmo7yMPl+bmwQ8pTZaCGFuLqCHD1ngo6ywHKIQy0nR249sAUVaCl2wGJwaO4JeOh1opUx8chzSBVRZBMz0/MGyygi7duYAff9JQqfH3p/BhDTNM8eKl6z5tnneZ8ZG5bG1XvqFTqWk4FhGsEWdK7B+He44hPjBxKQl2gmZAodb6g9YxfTHhVRKQY5hQ7KPXNvh3ikerHkoaL5apgsVBZJOTDE2KdYTnGLmqxghFx6L0ofqKI6hMr48ergMyflDk6wLNGWJvYHLWw==-MIIEPjCCAiagAwIBAgIBBTANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBMB4XDTE1MTEwMjA4MjE0OFoXDTE4MTEwMTA4MjE0OFowETEPMA0GA1UEAwwGcHJvZDN5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxcQkq+zdxlR2mmRYBPzGbUNdMN6OaXiXzxIWtMEkrJMO/5oUfQJbLLuMSMK0QHFmaI37WShyxZcfRCidwXjot4zmNBKnlyHodDij/78TmVqFl8nOeD5+07B8VEaIu7c3E1N+e1doC6wht4I4+IEmtsPAdoaj5WCQVQbrI8KeT8M9VcBIWX7fD0fhexfg3ZRt0xqwMcXGNp3DdJHiO0rCdU+Itv7EmtnSVq9jBG1usMSFvMowR25mju2JcPFp1+I4ZI+FqgR8gyG8oiNDyNEoAbsR3lOpI7grUYSvkB/xVy/VoklPCK2h0f0GJxFjnye8NT1PAywoyl7RmiAVRE/EKwIDAQABo4GZMIGWMAkGA1UdEwQCMAAwHQYDVR0OBBYEFGEpG9oZGcfLMGNBkY7SgHiMGgTcMEgGA1UdIwRBMD+AFKOetkhnQhI2Qb1t4Lm0oFKLl/GzoRykGjAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBggkA0myxg7KDeeEwEwYDVR0lBAwwCgYIKwYBBQUHAwEwCwYDVR0PBAQDAgWgMA0GCSqGSIb3DQEBCwUAA4ICAQC9WZuYgQedSuOc5TOUSrRigMw4/+wuC5EtZBfvdl4HT/8vzMW/oUlIP4YCvA0XKyBaCJ2iX+ZCDKoPfiYXiaSiH+HxAPV6J79vvouxKrWg2XV6ShFtPLP+0gPdGq3x9R3+kJbmAm8w+FOdlWqAfJrLvpzMGNeDU14YGXiZ9bVzmIQbwrBA+c/F4tlK/DV07dsNExihqFoibnqDiVNTGombaU2dDup2gwKdL81ua8EIcGNExHe82kjF4zwfadHk3bQVvbfdAwxcDy4xBjs3L4raPLU3yenSzr/OEur1+jfOxnQSmEcMXKXgrAQ9U55gwjcOFKrgOxEdek/Sk1VfOjvS+nuM4eyEruFMfaZHzoQiuw4IqgGc45ohFH0UUyjYcuFxxDSU9lMCv8qdHKm+wnPRb0l9l5vXsCBDuhAGYD6ss+Ga+aDY6f/qXZuUCEUOH3QUNbbCUlviSz6+GiRnt1kA9N2Qachl+2yBfaqUqr8h7Z2gsx5LcIf5kYNsqJ0GavXTVyWh7PYiKX4bs354ZQLUwwa/cG++2+wNWP+HtBhVxMRNTdVhSm38AknZlD+PTAsWGu9GyLmhti2EnVwGybSD2Dxmhxk3IPCkhKAK+pl0eWYGZWG3tJ9mZ7SowcXLWDFAk0lRJnKGFMTggrWjV8GYpw5bq23VmIqqDLgkNzuoog==
File --> Open //導入項目源碼(如AwesomeProject 源碼)
Setting-->Javascript-->選 React JSX
Setting-->Javascript-->Library --> Download 選 react 和react-native下載
}android
} git
{//=======================================入門==============================
http://reactnative.cn/docs/0.41/getting-started.html
{//最簡示例 helloworldgithub
> cd AwesomeProject
{//index.android.js 更改成下面內容
import React, { Component } from 'react'; //從模塊 'react'中導入 對象( React Component)
import { AppRegistry, Text } from 'react-native';算法
class HelloWorldApp extends Component {//定義繼承於Component的類 HelloWorldApp
render() {//渲染到真實的DOM上
return (
<Text>Hello world!</Text> //jsx語法(js中嵌入html標籤)
);
}
}npm
//註冊HelloWorldApp爲項目AwesomeProject的根組件(注意'AwesomeProject'必須和你init建立的項目名一致)
AppRegistry.registerComponent('AwesomeProject', () => HelloWorldApp);
}
> react-native run-android
json
{//JSX(js+xml -- js中嵌入html) --> 避免js html的割裂(頻繁查找dom元素),實現真正的組件化 windows
{//定製組件 Component
}
{//區分 html標籤和自定義組件 -- 大小寫
//---html標籤 小寫 (注: react native 裏不支持 h5 html標籤,它裏面全是對原生手機系統的api封裝)
<h1>entry</h1>
<div class="footer"> Copyright 2015.12.10. </div>
<input type="button" value="hello" onclick="msg()" />
//---自定義組件 大寫
<Text>Hello world!</Text>
}
}
}
{//定製組件屬性props(靜態: 一經指定,再也不更改)
{//設置圖片來源和寬高
//---index.android.js
import React, { Component } from 'react'; //從模塊 'react'中導入 對象( React Component)
import { AppRegistry, Image } from 'react-native'; //從模塊 'react-native'中導入Image對象
class HelloWorldApp extends Component {//定義繼承於Component的類 HelloWorldApp
render() {//渲染到真實的DOM上
return (
<Image
source={require('./img/menu_home.png')} //設置圖片來源屬性source,{} 是jsx語法(html標籤裏嵌入js)
style={{width:32,height:32}} //設置圖片風格屬性(圖片的寬高),裏面的{}表示是json對象
/>
);
}
}
//註冊HelloWorldApp爲項目AwesomeProject的根組件(注意'AwesomeProject'必須和你init建立的項目名一致)
AppRegistry.registerComponent('AwesomeProject', () => HelloWorldApp);
}
{//設置組件名字屬性
//---index.android.js
import React, { Component } from 'react';
import { AppRegistry,View } from 'react-native';
var MyComponent = require('./MyComponent'); //導入當前目錄下的MyComponent組件模塊
class HelloWorldApp extends Component {
render() {
return (
<View style={{alignItems: 'center'}}> /* 設置顯示佈局View 爲居中對齊顯示*/
<MyComponent name='yzg' /> /* 定製組件的屬性 name*/
<MyComponent name='ivan' />
</View>
);
}
}
AppRegistry.registerComponent('AwesomeProject', () => HelloWorldApp);
//---MyComponent.js
import React, { Component } from 'react';
import { Text } from 'react-native';
class MyComponent extends Component {
render() {
return (
<Text>Hello1 {this.props.name}!</Text> /*使用組件自己的屬性name*/
);
}
}
module.exports = MyComponent; //導出組件模塊
}
{//設置組件style樣式屬性
//---index.android.js
import React, { Component } from 'react';
import { AppRegistry } from 'react-native';
var MyComponent = require('./MyComponent'); //導入當前目錄下的MyComponent組件模塊
class HelloWorldApp extends Component {
render() {
return (
<MyComponent name='yzg' /> /* 定製組件的屬性 name*/
);
}
}
AppRegistry.registerComponent('AwesomeProject', () => HelloWorldApp);
//---MyComponent.js
import React, { Component } from 'react';
import { Text,StyleSheet } from 'react-native';
class MyComponent extends Component {
render() {
return (
<Text style={styles.bigblue}>Hello1 {this.props.name}!</Text>
);
}
}
const styles = StyleSheet.create({ //樣式集中設置(詳見組件API 如Text組件裏style屬性)
bigblue: {
color: 'blue',
fontWeight: 'bold',
fontSize: 30,
},
red: {
color: 'red',
},
});
module.exports = MyComponent; //導出組件模塊
}
}
{//定製組件狀態state(動態)
{//定時閃爍
//---index.android.js
import React, { Component } from 'react';
import { AppRegistry } from 'react-native';
var MyComponent = require('./MyComponent'); //導入當前目錄下的MyComponent組件模塊
class HelloWorldApp extends Component {
render() {
return (
<MyComponent name='yzg' /> /* 定製組件的屬性 name*/
);
}
}
AppRegistry.registerComponent('AwesomeProject', () => HelloWorldApp);
//---MyComponent.js
import React, { Component } from 'react';
import { Text } from 'react-native';
class MyComponent extends Component {
constructor(props) {//初始化組件(逐漸替換淘汰es5的getInitialState)
super(props); //繼承父屬性
this.state = { showText: true };
// 每1000毫秒對showText狀態作一次取反操做
setInterval(() => {
this.setState({ showText: !this.state.showText }); //動態更改狀態state
}, 1000);
}
render() {
// 根據當前showText的值決定是否顯示text內容
let display = this.state.showText ? this.props.name : ' ';
return (
<Text>{display}</Text>
);
}
}
module.exports = MyComponent; //導出組件模塊
}
}
{//組合多個組件
{//用View組合多個組件
import React, { Component } from 'react';
import { Text,View,Image } from 'react-native';
//注:render渲染時,只能return一個element,多個時加View,不然會報錯JSX elements must be wrapped in an enclosing tag
class MyComponent extends Component {
render() {
return (//return 多個組件時需用View包裹起來
<View >
<Text>Hello</Text>
<Image
source={require('./img/menu_home.png')} //設置圖片來源屬性source,{} 是jsx語法(html標籤裏嵌入js)
style={{width:32,height:32}} //設置圖片風格屬性(圖片的寬高),裏面的{}表示是json對象
/>
</View>
);
}
}
module.exports = MyComponent; //導出組件模塊
}
{//安排組件位置(彈性佈局Flex)
import React, { Component } from 'react';
import { Text,View,Image } from 'react-native';
//注:render渲染時,只能return一個element,多個時加View,不然會報錯JSX elements must be wrapped in an enclosing tag
class MyComponent extends Component {
render() {
return (//return 多個組件時需用View包裹起來
<View style={{
flex: 2,
flexDirection: 'row', //設置佈局的主軸(默認爲column 列)爲行row
justifyContent: 'center', //子元素沿着主軸的排列方式flex-start、center、flex-end、space-around以及space-between
alignItems: 'flex-end', //次軸(與主軸垂直)排列 flex-start、center、flex-end以及stretch(伸縮要生效,子元素不能有固定尺寸)
}} >
<Text>Hello</Text>
<Image
source={require('./img/menu_home.png')} //設置圖片來源屬性source,{} 是jsx語法(html標籤裏嵌入js)
/>
</View>
);
}
}
module.exports = MyComponent; //導出組件模塊
}
{//列表滾動顯示ListView
{//最簡ListView
//注:通常不用ScrollView(性能較差)
import React, { Component } from 'react';
import {Text,ListView } from 'react-native';
//注:render渲染時,只能return一個element,多個時加View,不然會報錯JSX elements must be wrapped in an enclosing tag
class MyComponent extends Component {
constructor(props) {
super(props);
//ListView 會根據rowHasChanged算法去檢查數據更新,決定哪些行須要從新渲染
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
dataSource: ds.cloneWithRows([
'yzg', 'ivan',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
])
};
}
render() {
return (
<ListView
dataSource={this.state.dataSource} //列表的數據源
renderRow={(rowData) => <Text>{rowData}</Text>} //逐個解析數據源渲染顯示(渲染誰由rowHasChanged決定)
/>
);
}
}
module.exports = MyComponent; //導出組件模塊
}
{//---index.android.js
import React, { Component } from 'react';
import { AppRegistry } from 'react-native';
var StoryList = require('./StoryList'); //導入當前目錄下的MyComponent組件模塊
class HelloWorldApp extends Component {
render() {
return (
<StoryList />
);
}
}
AppRegistry.registerComponent('AwesomeProject', () => HelloWorldApp);
}
{//---StoryList.js
import React, { Component } from 'react';
import {Text,ListView } from 'react-native';
var StoryItem = require('./StoryItem'); //導入當前目錄下的MyComponent組件模塊
//注:render渲染時,只能return一個element,多個時加View,不然會報錯JSX elements must be wrapped in an enclosing tag
class StoryList extends Component {
constructor(props) {
super(props);
//ListView 會根據rowHasChanged算法去檢查數據更新,決定哪些行須要從新渲染
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
dataSource: ds.cloneWithRows([//設置列表的數據源
{name:'yzg',pic:require('./img/menu_home.png')},
{name:'ivan',pic:require('./img/ic_back_white.png')},
{name:'lili',pic:require('./img/ic_collect_white.png')},
{name:'wang',pic:require('./img/ic_collected_white.png')},
])
};
}
render() {
return (
<ListView
dataSource={this.state.dataSource} //列表的數據源
renderRow={(rowData) => <StoryItem obj={rowData} />} //逐個解析數據源渲染顯示(渲染誰由rowHasChanged決定)
/>
);
}
}
module.exports = StoryList; //導出組件模塊
}
{//---StoryItem.js
import React, { Component } from 'react';
import { Text,View,Image } from 'react-native';
//注:render渲染時,只能return一個element,多個時加View,不然會報錯JSX elements must be wrapped in an enclosing tag
class StoryItem extends Component {
render() {
return (//return 多個組件時需用View包裹起來
<View >
<Text>{this.props.obj.name} </Text>
<Image
source={this.props.obj.pic} //設置圖片來源屬性source,{} 是jsx語法(html標籤裏嵌入js)
/>
</View>
);
}
}
module.exports = StoryItem; //導出組件模塊
}
}
}
}
}