【新東網(wǎng)技術(shù)大咖帶您走進(jìn)React Native】用它就可通吃移動(dòng)端開發(fā)
發(fā)布時(shí)間: 2016-09-09 11:58:01
文/閆立幫 華西研發(fā)部
新東網(wǎng)自2001年成立以來,掌握大數(shù)據(jù)、云計(jì)算、通信、物聯(lián)網(wǎng)及區(qū)塊鏈等信息技術(shù),擁有一支逾16年經(jīng)驗(yàn)的強(qiáng)大IT團(tuán)隊(duì)。為沉淀企業(yè)技術(shù)實(shí)力,繼續(xù)發(fā)揮行業(yè)優(yōu)勢(shì),《東網(wǎng)快訊》特邀新東網(wǎng)技術(shù)大咖帶您走進(jìn)這些先進(jìn)信息技術(shù),揭秘新東網(wǎng)16年來的技術(shù)成果,每周五發(fā)布。
一、React Native 是什么
React Native 是 Facebook 推出的一個(gè)用 Java 語言就能同時(shí)編寫 ios,android,以及后臺(tái)的一項(xiàng)技術(shù)。用大白話說,就是從此一名程序員只用這一門技術(shù),就可以同時(shí)寫出 android app,ios app,以及后臺(tái)應(yīng)用程序。而app 也能做到向網(wǎng)頁程序那樣隨時(shí)都能更新了。是不是很牛逼?是不是很牛逼?是不是很牛逼?重要的事問三遍!嗯,真的很牛逼。
那么我們來看看React Native 受到了如此大的關(guān)注,它的優(yōu)越性到底在什么地方呢?React Native整套解決方案完成了江湖統(tǒng)一,F(xiàn)aceBook 也號(hào)稱這門技術(shù)是 “Learn Once,Write AnyWhere”,即學(xué)習(xí)成本只有一次,卻完成了所有開發(fā)角色的統(tǒng)一。
1.app 將來都是可像網(wǎng)頁一樣隨時(shí)更新,隨時(shí)發(fā)布。
2.對(duì)于一名開發(fā)人員,將再也沒有前端、終端、后臺(tái)的區(qū)分,他所關(guān)注的就是做一整套應(yīng)用程序,人力資源將得到最大程度的整合與釋放。
3.代碼復(fù)用將會(huì)是主旋律,因?yàn)槭且环N語言,大家重復(fù)造輪子的成本會(huì)越來越節(jié)省。
目前,React Native 也還是有一些缺點(diǎn)的,比如他的 sdk 組件包 size 還比較大,crash 還比較多,在 ios 上支持的內(nèi)容已經(jīng)相當(dāng)不錯(cuò)了,但在android上 支持則還屬于初級(jí)階段。不過,這些都只是一個(gè)新技術(shù)剛剛誕生時(shí)存在的普遍性問題,相信隨著技術(shù)不斷地發(fā)展與完善,將都不再是問題。
二、React Native 的技術(shù)優(yōu)勢(shì)
React Native作為Facebook推出的一個(gè)開源框架,實(shí)現(xiàn)以JavaScript開發(fā)移動(dòng)應(yīng)用,具有如下優(yōu)勢(shì):
1. JavaScript使用門檻低、普及率高 。
2. 使用JavaScript開發(fā),開發(fā)成本低:移動(dòng)端(iOS和Android平臺(tái)上),由于內(nèi)置瀏覽器都采用Webkit內(nèi)核,因而在使用JavaScript開發(fā)時(shí),完全無需考慮瀏覽器兼容問題,進(jìn)一步降低了JavaScript的開發(fā)成本。
3. React Native采用了JSX語法糖工具。JSX是一種語法轉(zhuǎn)換工具,能夠?qū)ML標(biāo)簽轉(zhuǎn)換為JavaScript代碼。這意味著,你可以在JavaScript里像寫XML一樣去寫JavaScript代碼,不用手動(dòng)拼接XML格式的字符串,不用顯示地創(chuàng)建標(biāo)簽和執(zhí)行插入標(biāo)簽操作,而且這樣寫出來的代碼可讀性非常強(qiáng),降低維護(hù)成本。
4. 原生UI,UI交互效率高。React Native未采用WEB模式,而是使用JavaScript去開發(fā)原生應(yīng)用。React Native自己實(shí)現(xiàn)了一套與原生語言通訊的機(jī)制,將JavaScript視為數(shù)據(jù)源,用原生語言去調(diào)用數(shù)據(jù)源,然后用原生UI來展示,用原生語言來實(shí)現(xiàn)事件機(jī)制,這樣便不再有瀏覽器單線程、DOM渲染效率低導(dǎo)致的交互體驗(yàn)差的問題。由于JavaScript和原生語言的運(yùn)行效率很高,因而應(yīng)用交互體驗(yàn)非常好,堪比原生應(yīng)用。
5. React Ntive與Hybird app、Native APP 的優(yōu)勢(shì)對(duì)比分析
React Ntive與Hybird app優(yōu)勢(shì)對(duì)比分析:
1) 不用Webview,徹底擺脫了Webview讓人不爽的交互和性能問題
2)有較強(qiáng)的擴(kuò)展性,這是因?yàn)镹ative端提供的是基本控件,JS可以自由組合使用
3) 可以直接使用Native原生的「牛逼」動(dòng)畫(在FB Group這個(gè)app里面,面板滑出帶一點(diǎn)果凍彈動(dòng),面板基于某個(gè)點(diǎn)展開這種動(dòng)畫隨處可見,這種動(dòng)畫用Native code來做小菜一碟,但是用Web來做就難上加難)。
優(yōu)勢(shì)相對(duì)于Native app: 可以通過更新遠(yuǎn)端JS,直接更新app。
三、React Native 的應(yīng)用實(shí)例
這里選用攜程的App首頁作為例子。整個(gè)頁面我們可以分為頭部導(dǎo)航欄、 圖片輪播、 9宮格、底部活動(dòng)這幾個(gè)部分,大致如下:
1、頭部導(dǎo)航欄
在React-Native中實(shí)現(xiàn)頭部導(dǎo)航欄很簡單,只要使用NavigatorIOS組件即可?,F(xiàn)在開工。
1、我們?cè)?/span>index.ios.js中添加如下代碼;同時(shí)創(chuàng)建文件夾pagaes和pages下創(chuàng)建Index.js
var React = require(‘react-native‘);
var Index = require(‘./pages/Index‘);
var {
NavigatorIOS,
AppRegistry,
StyleSheet,
} = React;
var NV = React.createClass({
render: function(){
return(
style={styles.container}
initialRoute={{
title: ‘首頁‘,
component: Index,
}}
/>
);
}
});
var styles = StyleSheet.create({
container: {
flex: 1,
}
});
AppRegistry.registerComponent(‘HelloWorld‘, () => NV);
分析代碼:
(1)require:引入外部模塊,就像,引入我們自己創(chuàng)建的/pages/Index.js一樣。
(2)引入定義NavigatorIOS、AppRegistry、StyleSheet組件和類。
(3)在render中調(diào)用NavigatorIOS組件,initialRoute是初始化路由,title是當(dāng)前頁面的頭部標(biāo)題;component是當(dāng)前路由下顯示的組件;
(4)注意:這里NavigatorIOS的style需要設(shè)置大小,比如這里設(shè)置是flex:1,否則就不能顯示內(nèi)容主體;
(5)最后我們需要注冊(cè)當(dāng)前應(yīng)用:AppRegistry.registerComponent(‘HelloWorld‘, () => NV);
2、創(chuàng)建Index.js文件,文件的內(nèi)容如下, module.exports就暴露了Index模塊。
效果如下圖:
2、圖片輪播
這里圖片輪播使用的是第三方組件react-native-swiper,當(dāng)然React-Native是支持transform可以直接實(shí)現(xiàn)一套。我們啟動(dòng)npm命令行,在項(xiàng)目的根目錄使用如下命令安裝模塊。
$ npm react-native-swiper --save
安裝完成后,我們需要完成輪播功能。因?yàn)榭梢缘?/span>github看看swiper暴露的接口和參數(shù)。github地址是:https://github.com/leecade/react-native-swiper
(1)引入swiper,前面也提到了require.
var Swiper = require(‘react-native-swiper‘);
(2)使用swiper,將輪播圖封裝成單獨(dú)的組件
var sliderImgs = [
‘http://images3.c-ctrip.com/SBU/apph5/201505/16/app_home_ad16_640_128.png‘,
‘http://images3.c-ctrip.com/rk/apph5/C1/201505/app_home_ad49_640_128.png‘,
‘http://images3.c-ctrip.com/rk/apph5/D1/201506/app_home_ad05_640_128.jpg‘
];
var Slider = React.createClass({
render: function(){
return (
);
}
});
(3)這樣我們可以直接在render的時(shí)候直接用:
3、完成第一個(gè)9宮格布局
4個(gè)九宮格都是一樣,實(shí)可以封裝成組件,這里采用拷貝的形式,開發(fā)一個(gè),其他3個(gè)就ok的,會(huì)偷懶是一種智慧。分析下布局:
(1)首先是3個(gè)列在一行的布局,那么外層組件是需要flexDirection: ‘row‘,各占據(jù)寬度的1/3,即各自flex:1;
(2)每個(gè)列內(nèi)又分兩行, 需要每個(gè)行都是flex:1,各占據(jù)高度的一半;
(3)第一列是文字圖片組合,其余都是文字組合;
(4)所有行內(nèi)元素都是水平、垂直居中;
(5)這里使用了個(gè)TouchableHighlight組件,是為了出發(fā)onPress事件,類似于click或者touch事件。
4、樣式類
說完了布局的原理,這里需要貼上樣式僅供參考:
var styles = StyleSheet.create({
//container
container:{
backgroundColor:‘#F2F2F2‘,
flex:1,
},
//slider
wrapper: {
height:80,
},
slide: {
height:80,
resizeMode: Image.resizeMode.contain,
},
//sbu
sbu_view:{
height:84,
marginLeft: 5,
marginRight:5,
borderWidth:1,
borderRadius:5,
marginBottom:10,
flexDirection:‘row‘,
},
sbu_red:{
backgroundColor: ‘#FA6778‘,
borderColor:‘#FA6778‘,
marginTop:-70,
},
sbu_blue:{
backgroundColor: ‘#3D98FF‘,
borderColor:‘#3D98FF‘,
},
sbu_green:{
backgroundColor: ‘#5EBE00‘,
borderColor:‘#5EBE00‘,
},
sbu_yellow:{
backgroundColor: ‘#FC9720‘,
borderColor:‘#FC9720‘,
},
sbu_flex:{
flex:1,
},
sbu_borderRight:{
borderColor:‘#fff‘,
borderRightWidth: 0.5,
},
sbu_icon_img:{
height:40,
width:40,
resizeMode:Image.resizeMode.contain,
},
sub_con_flex:{
flex:1,
justifyContent: ‘center‘,
alignItems: ‘center‘,
},
sub_text:{
justifyContent:‘center‘,
},
font16:{
fontSize:17,
color:‘#FFF‘,
fontWeight:‘900‘,
},
sbu_borderBottom:{
borderBottomWidth:0.5,
borderBottomColor:‘#fff‘,
},
img_view:{
height:62,
marginLeft:5,
marginRight:5,
flexDirection: ‘row‘,
marginBottom:20,
backgroundColor:‘#fff‘,
},
img_flex:{
flex:1,
borderWidth:1,
borderColor:‘#ccc‘,
},
img_wh: {
height:59,
borderRightWidth:0,
resizeMode:Image.resizeMode.contain,
}
});
著重說下resizeMode:Image.resizeMode.contain。在React-Native中圖片的大小是不會(huì)根據(jù)給定一個(gè)寬度或者高度而自適應(yīng)大小的,因此我們需要讓圖片根據(jù)寬度或者高度來自適應(yīng),那么可以使用resizeMode:Image.resizeMode.contain。