翻譯 | 《JavaScript Everywhere》第22章 移動應用程式shell
翻譯 | 《JavaScript Everywhere》第22章 移動應用程式shell
寫在最前面
大家好呀,我是毛小悠,是一位前端開發工程師。正在翻譯一本英文技術書籍。
為了提高大家的閱讀體驗,對語句的結構和內容略有調整。如果發現本文中有存在瑕疵的地方,或者你有任何意見或者建議,可以在評論區留言,或者加我的微信:code_maomao,歡迎相互溝通交流學習。
(σ゚∀゚)σ…:*☆哎喲不錯哦
第22章 移動應用程式shell
我妻子是一位攝影師,這意味著她的大部分生活都是基於在矩形框中構圖。在攝影中,有很多變數-物體,光線,角度,但是影像的比例保持一致。在這種限制下,不可思議的事情發生了,塑造了我們看待和記住周圍世界的方式。移動應用程式開發提供了類似的機會。在小巧的矩形螢幕的約束下,我們可以構建具有沉浸式使用者體驗的功能強大的應用程式。
在本章中,我們將開始為應用程式構建shell
。為此,我們首先將仔細研究React Native
元件的一些關鍵構建塊。然後,我們將通過React Native
的內建樣式支援以及我們選擇的CSS-in-JS
庫樣式元件,研究如何將樣式應用於我們的應用程式。在介紹瞭如何應用樣式之後,我們將看看如何將路由整合到我們的應用程式中。最後,我們將探索如何使用圖示輕鬆增強我們的應用程式介面。
React Native構建塊
讓我們先來看一下React Native
應用程式的基本構建塊。你可能已經猜到React Native
應用程式包含用JSX
編寫的React
元件。但是,如果沒有HTML
頁面的DOM
(文件物件模組),這些元件到底有什麼用?我們可用於從src/Main.js
的“ Hello World
”元件開始。現在,我已經刪除了樣式:
import React from 'react';
import { Text, View } from 'react-native';
const Main = () => {
return (
<View>
<Text>Hello world!</Text>
</View>
);
};
export default Main;
在此標記中,有兩個著名的JSX
標籤:
和 .
。如果你有網頁開發經驗,就知道標籤與標籤的用途大致相同。它是我們應用程式內容的容器。靠它們自己並不能做很多事,但是它們包含了我們應用程式的所有內容,可以相互巢狀,並可以應用樣式。我們的每個元件都將包含在中。
在React Native
中,你可以在Web
任何地方使用標籤。毫無疑問,該標籤用於包含我們應用中的任何文字。
但是,與網頁不同,該標籤用於所有文字。我們還可以通過使用JSX
元素來新增圖片到我們的應用中。
讓我們更新我們的* src/Main.js
*檔案以包含影像。要做到這一點,我們從React Native匯入了Image
元件並使用一個有src屬性的標記(見圖22-1
):
import React from 'react';
import { Text, View, Image } from 'react-native';
const Main = () => {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Hello world!</Text>
<Image source={require('../assets/images/hello-world.jpg')} />
</View>
);
};
export default Main;
前面的程式碼在檢視中渲染了一些文字和影像。你可能會注意到,我們的標記和JSX
標記是傳遞的屬性,這些屬性使我們能夠控制特定的行為(在這種情況下,是檢視的樣式和影像的來源)。
將屬性傳遞給元素可以使我們擴充套件元素的各種附加功能。React Native
的API
文件對每個元素可用的屬性進行了分類。
圖22-1
。使用<Image
>標籤,我們可以將影像新增到我們的應用程式中(Windell Oskay
攝)
我們的應用程式並沒有做很多事情,但是在下一節中,我們將探討如何使用React Native
的內建樣式支援和樣式化元件來改善外觀。
樣式和樣式元件
作為應用程式開發人員和設計師,我們希望能夠對應用程式進行樣式設定,可以具有良好的外觀、感覺和使用者體驗。有許多UI
元件庫,例如NativeBase
或React Native Elements
,通常提供了許多預定義且可自定義的元件。
這些都是值得一看的,但出於我們的目的,讓我們探索如何組合自己應用程式的樣式和佈局。
正如我們已經看到的,React Native
提供了一個style
屬性,該屬性允許我們將自定義樣式應用於應用程式中的任何JSX
元素。樣式名稱和值與CSS
的樣式名稱和值匹配,除了名稱使用camelCase
編寫外,例如lineHeight
和backgroundColor
。讓我們更新/src/Main.js
檔案,使其包含元素的某些樣式(參見圖22-2
):
const Main = () => {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text style={{ color: '#0077cc', fontSize: 48, fontWeight: 'bold' }}>
Hello world!
</Text>
<Image source={require('../assets/images/hello-world.jpg')} />
</View>
);
};
圖22-2
使用樣式我們可以調整<Text
>元素的外觀
你可能會認為,在元素級別應用樣式會很快變得難以維護。我們可以使用React Native
的StyleSheet
庫來幫助組織和重用我們的樣式。
首先,我們需要將StyleSheet
新增到匯入列表中(圖22-3
):
import { Text, View, Image, StyleSheet } from 'react-native';
現在我們可以抽象出樣式:
const Main = () => {
return (
<View style={styles.container}>
<Text style={styles.h1}>Hello world!</Text>
<Text style={styles.paragraph}>This is my app</Text>
<Image source={require('../assets/images/hello-world.jpg')} />
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center'
},
h1: {
fontSize: 48,
fontWeight: 'bold'
},
paragraph: {
marginTop: 24,
marginBottom: 24,
fontSize: 18
}
});
彈性盒Flexbox
React Native
使用CSS flexbox
演算法定義佈局樣式。我們不會深入介紹flexbox
,但是React Native
提供的文件清楚地說明了flexbox
及其如何在螢幕上排列元素的案例。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-z9Ipy9fi-1606433567748)(http://vipkshttp0.wiz.cn/ks/share/resources/c46f74f8-50d4-4015-8658-189fa6382bb9/3605e53d-a36d-4996-be90-cd98a055256a/index_files/3d8da063-0966-4016-892e-47d00d20fd54.jpg)]
圖22-3
通過使用樣式表,我們可以縮放應用程式的樣式
樣式化的元件
儘管React Native
的內建樣式屬性和StyleSheets
可以提供我們開箱即用的所有功能,但它們遠不是我們設計應用程式樣式的唯一選擇。
我們還可以利用流行的Web CSS-in-JS
解決方案,例如Styled Components
和Emotion
。我認為這些提供了更簡潔的語法,與CSS
更加緊密地結合在一起,並限制了Web
和移動應用程式程式碼庫之間所需的轉換的程式碼量。使用這些啟用了Web CSS-in-JS
庫也為跨平臺共享樣式或元件創造了機會。為了實現我們的目的,讓我們看一下如何使上一個示例適應使用Styled Components
庫。首先,在src/Main.js
中,我們將匯入庫的本機版本:
import styled from 'styled-components/native'
從這裡我們可以將樣式遷移到樣式化元件語法。如果已經按照了第13
章的說明進行操作,則此語法應該非常熟悉。我們的src/Main.js
檔案的最終程式碼變為:
import React from 'react';
import { Text, View, Image } from 'react-native';
import styled from 'styled-components/native';
const StyledView = styled.View`
flex: 1;
justify-content: center;
`;
const H1 = styled.Text`
font-size: 48px;
font-weight: bold;
`;
const P = styled.Text`
margin: 24px 0;
font-size: 18px;
`;
const Main = () => {
return (
<StyledView>
<H1>Hello world!</H1>
<P>This is my app.</P>
<Image source={require('../assets/images/hello-world.jpg')} />
</StyledView>
);
};
export default Main;
樣式化的元件大寫
在樣式化元件庫中,元素名稱必須始終大寫。這樣,我們現在可以將自定義樣式應用於我們的應用程式,並可以選擇使用React Native
的內建樣式系統或樣式化元件庫。
路由
在網頁上,我們可以使用HTML
錨連結將一個HTML
文件連結到任何其他文件,包括我們自己網站上的文件。對於JavaScript
驅動的應用程式,我們使用路由將JavaScript
渲染的模板連結在一起。那麼移動應用程式呢?對於這些,我們將在螢幕之間路由使用者。在本節中,我們將探討兩種常見的路由型別:基於選項卡的導航和堆疊導航。
使用React
導航的選項卡式路由
為了執行路由,我們將利用React Navigation
庫,這是React Native
和Expo
團隊推薦的路由解決方案。最重要的是,它使實現帶有平臺特定的外觀通用路由模式變得非常簡單。
首先,讓我們首先在src
目錄中建立一個名為screens
的新目錄。在screens
目錄中,讓我們建立三個新檔案,每個檔案包含一個非常基本的React
元件。
在src/screens/favorites.js
中新增以下內容:
import React from 'react';
import { Text, View } from 'react-native';
const Favorites = () => {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Favorites</Text>
</View>
);
};
export default Favorites;
在src/screens/feed.js
中新增它:
import React from 'react';
import { Text, View } from 'react-native';
const Feed = () => {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Feed</Text>
</View>
);
};
export default Feed;
最後,將其新增到src/screens/mynotes.js
中:
import React from 'react';
import { Text, View } from 'react-native';
const MyNotes = () => {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>My Notes</Text>
</View>
);
};
export default MyNotes;
然後,我們可以在src/screens/index.js
中建立一個新檔案,用作我們應用程式路由的根目錄。我們將從匯入初始的react
和react-navigation
依賴關係開始:
import React from 'react';
import { createAppContainer } from 'react-navigation';
import { createBottomTabNavigator } from 'react-navigation-tabs';
// import screen components
import Feed from './feed';
import Favorites from './favorites';
import MyNotes from './mynotes';
匯入這些依賴項後,我們可以使用React Navigation
的createBottomTabNavigator
,在這三個螢幕之間建立一個標籤導航器,定義應在我們的導航中顯示哪些React
元件螢幕:
const TabNavigator = createBottomTabNavigator({
FeedScreen: {
screen: Feed,
navigationOptions: {
tabBarLabel: 'Feed',
}
},
MyNoteScreen: {
screen: MyNotes,
navigationOptions: {
tabBarLabel: 'My Notes',
}
},
FavoriteScreen: {
screen: Favorites,
navigationOptions: {
tabBarLabel: 'Favorites',
}
}
});
// create the app container
export default createAppContainer(TabNavigator);
最後,讓我們更新src/Main.js
檔案,除了匯入路由器之外什麼也不做。現在應簡化為以下內容:
import React from 'react';
import Screens from './screens';
const Main = () => {
return <Screens />;
};
export default Main;
通過在終端中輸入npm start
命令,確保你的應用程式正在執行。現在,你應該在螢幕底部看到選項卡導航,在其中點選選項卡會將你轉到適當的螢幕(圖22-4
)。
圖22-4
現在我們可以使用選項卡式導航在螢幕之間導航
堆疊導航
第二種路由選擇型別是堆疊導航,其中概念上將螢幕“堆疊”在一起,從而使使用者可以更深入地瀏覽堆疊。考慮一個新聞應用程式,使用者在其中檢視文章的摘要。使用者可以點選新聞文章標題,並在堆疊中更深入地瀏覽到文章內容。
然後,他們可以單擊“後退”按鈕,導航迴文章提要,或者導航到另一個文章標題,從而更深入地瀏覽堆疊。
在我們的應用程式中,我們希望使用者能夠從筆記的摘要切換到筆記本身並返回。
讓我們看看如何為每個螢幕實現堆疊導航。首先,讓我們建立一個新的NoteScreen
元件,它將包含堆疊中的第二個螢幕。使用最少的React Native
元件在src/screens/note.js
上建立一個新檔案:
import React from 'react';
import { Text, View } from 'react-native';
const NoteScreen = () => {
return (
<View style={{ padding: 10 }}>
<Text>This is a note!</Text>
</View>
);
};
export default NoteScreen;
接下來,我們將對路由器進行更改,啟用NoteScreen
元件的堆疊導航。為此,我們將從react-navigation-stack
以及新的note.js
元件匯入createStackNavigator
。在src/screens/index.js
中,將匯入內容更新如下:
import React from 'react';
import { Text, View, ScrollView, Button } from 'react-native';
import { createAppContainer } from 'react-navigation';
import { createBottomTabNavigator } from 'react-navigation-tabs';
// add import for createStackNavigator
import { createStackNavigator } from 'react-navigation-stack';
// import screen components, including note.js
import Feed from './feed';
import Favorites from './favorites';
import MyNotes from './mynotes';
import NoteScreen from './note';
通過匯入我們的庫和檔案,我們可以實現堆疊導航功能。在我們的路由器檔案中,我們必須告訴React Navigation
哪些螢幕是“可重疊的”。對於我們每個選項卡式路由,我們希望使用者能夠導航到“筆記”螢幕。繼續並按如下所示定義這些堆疊:
const FeedStack = createStackNavigator({
Feed: Feed,
Note: NoteScreen
});
const MyStack = createStackNavigator({
MyNotes: MyNotes,
Note: NoteScreen
});
const FavStack = createStackNavigator({
Favorites: Favorites,
Note: NoteScreen
});
現在,我們可以更新TabNavigator
來引用堆疊,而不是單個螢幕。為此,請更新每個TabNavigator
物件中的screen
屬性:
const TabNavigator = createBottomTabNavigator({
FeedScreen: {
screen: FeedStack,
navigationOptions: {
tabBarLabel: 'Feed'
}
},
MyNoteScreen: {
screen: MyStack,
navigationOptions: {
tabBarLabel: 'My Notes'
}
},
FavoriteScreen: {
screen: FavStack,
navigationOptions: {
tabBarLabel: 'Favorites'
}
}
});
總之,我們的src/screens/index.js
檔案應如下所示:
import React from 'react';
import { Text, View, ScrollView, Button } from 'react-native';
import { createAppContainer } from 'react-navigation';
import { createBottomTabNavigator } from 'react-navigation-tabs';
import { createStackNavigator } from 'react-navigation-stack';
// import screen components
import Feed from './feed';
import Favorites from './favorites';
import MyNotes from './mynotes';
import NoteScreen from './note';
// navigation stack
const FeedStack = createStackNavigator({
Feed: Feed,
Note: NoteScreen
});
const MyStack = createStackNavigator({
MyNotes: MyNotes,
Note: NoteScreen
});
const FavStack = createStackNavigator({
Favorites: Favorites,
Note: NoteScreen
});
// navigation tabs
const TabNavigator = createBottomTabNavigator({
FeedScreen: {
screen: FeedStack,
navigationOptions: {
tabBarLabel: 'Feed'
}
},
MyNoteScreen: {
screen: MyStack,
navigationOptions: {
tabBarLabel: 'My Notes'
}
},
FavoriteScreen: {
screen: FavStack,
navigationOptions: {
tabBarLabel: 'Favorites'
}
}
});
// create the app container
export default createAppContainer(TabNavigator);
如果我們在模擬器或裝置上的Expo
應用程式中開啟應用程式,則不會發現明顯區別。這是因為我們尚未向堆疊導航新增連結。讓我們更新src/screens/feed.js
元件以包括一個堆疊的導航連結。
為此,首先包括React Native
的Button
依賴項:
import { Text, View, Button } from 'react-native';
現在,我們可以包括一個按鈕,在按下該按鈕時,將導航到note.js
元件的內容。我們將傳遞元件props
,其中將包含導航資訊,並新增一個包含標題和onPress
道具的:
const Feed = props => {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Note Feed</Text>
<Button title="Keep reading" onPress={() => props.navigation.navigate('Note')}
/>
</View>
);
};
這樣,我們應該能夠在螢幕之間進行導航。單擊“Feed”螢幕中的按鈕以導航至“Node”螢幕,然後單擊箭頭以返回(圖22-5
)。
圖22-5
單擊按鈕連結將導航到新螢幕,而單擊箭頭將使使用者返回上一螢幕
新增螢幕標題
新增堆疊導航器會自動在我們的應用程式頂部新增標題欄。我們可以設定樣式,甚至刪除該頂部欄。現在,讓我們在堆疊頂部的每個螢幕上新增一個標題。為此,我們將在元件本身之外設定元件NavigationOptions
。在src/screens/feed.js
中:
import React from 'react';
import { Text, View, Button } from 'react-native';
const Feed = props => {
// component code
};
Feed.navigationOptions = {
title: 'Feed'
};
export default Feed;
我們可以對其他螢幕元件重複此過程。
在src/screens/favorites.js
中:
Favorites.navigationOptions = {
title: 'Favorites'
};
在src/screens/mynotes.js
中:
MyNotes.navigationOptions = {
title: 'My Notes'
};
現在,我們每個螢幕的頂部導航欄都將包含一個標題(圖22-6
)。
圖22-6
在navigationOptions
中設定標題會將其新增到頂部導航欄
Icons
目前,我們的導航功能已完成,但缺少視覺化元件以使使用者使用更友好。值得慶幸的是,Expo
使在我們的應用程式中包含圖示變得異常容易。我們可以搜尋Expo
提供的所有圖示expo.github.io/vector-icons
。包括許多圖示集,例如Ant Design
,Ionicons
,Font Awesome
,Entypo
,Foundation
,Material
圖示和Material Community
圖示。這為我們提供了開箱即用的多種選擇。
讓我們在選項卡式導航中新增一些圖示。首先,我們必須匯入我們要使用的圖示集。在我們的案例中,我們將通過在src/screens/index.js
中新增以下內容來使用Material Community
圖示:
import { MaterialCommunityIcons } from '@expo/vector-icons';
現在,我們想在元件中使用圖示的任何地方,都可以將其包含在JSX
中,包括設定屬性,例如大小和顏色:
<MaterialCommunityIcons name="star" size={24} color={'blue'} />
我們將圖示新增到標籤導航中。React Navigation
包含一個名為tabBarIcon
的屬性,該屬性允許我們設定圖示。我們可以將此作為函式傳遞,使我們能夠設定tintColor
,以便活動選項卡圖示的顏色與非活動圖示的顏色不同:
const TabNavigator = createBottomTabNavigator({
FeedScreen: {
screen: FeedStack,
navigationOptions: {
tabBarLabel: 'Feed',
tabBarIcon: ({ tintColor }) => (
<MaterialCommunityIcons name="home" size={24} color={tintColor} />
)
}
},
MyNoteScreen: {
screen: MyStack,
navigationOptions: {
tabBarLabel: 'My Notes',
tabBarIcon: ({ tintColor }) => (
<MaterialCommunityIcons name="notebook" size={24} color={tintColor} />
)
}
},
FavoriteScreen: {
screen: FavStack,
navigationOptions: {
tabBarLabel: 'Favorites',
tabBarIcon: ({ tintColor }) => (
<MaterialCommunityIcons name="star" size={24} color={tintColor} />
)
}
}
});
這樣,我們的選項卡式導航將顯示圖示(圖22-7
)。
圖22-7
我們應用程式的導航現在包括圖示
結論
在本章中,我們介紹瞭如何構建React Native
應用程式的基本元件。現在,你可以建立元件,向其中新增樣式並在它們之間導航。希望通過此基本設定,你可以看到React Native
的驚人潛力。藉助最少的新技術,你已經可以打造令人印象深刻且專業的移動應用程式的起點。在下一章中,我們將使用GraphQL
在應用程式中包含來自API
的資料。
如果有理解不到位的地方,歡迎大家糾錯。如果覺得還可以,麻煩您點贊收藏或者分享一下,希望可以幫到更多人。
相關文章
- 翻譯 | 《JavaScript Everywhere》第18章 帶Electron的桌面應用程式JavaScript
- [譯] 設計大型 JavaScript 應用程式JavaScript
- [譯] PWA 會取代原生移動應用嗎?
- [Flutter翻譯]釋出您的Flutter桌面應用程式Flutter
- [翻譯]JavaScript的成本JavaScript
- 『翻譯』JavaScript 函數語言程式設計JavaScript函數程式設計
- 移動應用程式開發簡介!
- 安卓應用安全指南翻譯完成安卓
- [翻譯]理解非同步JavaScript非同步JavaScript
- 使用Webpack提升Vue.js應用程式的4種方法(翻譯)WebVue.js
- [譯] 使用Capacitor 和 Vue.js 構建移動應用Vue.js
- 【翻譯】基於 Cypress 測試 React 應用React
- 對《JavaScript高階程式設計(第4版)》一書中為何要翻譯promise的回覆JavaScript程式設計Promise
- [翻譯] 響應式程式設計(Reactive Programming) - 流(Streams) - BLoC - 實際應用案例程式設計ReactBloC
- [Web翻譯]JavaScript中的編譯與填充WebJavaScript編譯
- [Flutter翻譯]我希望在構建Flutter應用程式之前知道的事情Flutter
- 翻譯:《實用的Python程式設計》InstructorNotesPython程式設計Struct
- 用於管理應用程式得shell指令碼指令碼
- 騰訊互動翻譯的坑爹翻譯
- [譯] CSS 變數和 JavaScript 讓應用支援動態主題CSS變數JavaScript
- 程式設計=翻譯?程式設計
- JavaScript 事件迴圈詳解(翻譯)JavaScript事件
- 文件翻譯器怎麼用?如何翻譯Word文件?
- [譯] 如何編寫全棧 JavaScript 應用全棧JavaScript
- Spring Shell應用程式開發流程解析Spring
- 爬取必應翻譯
- 如何使用JavaScript開發AR(擴增實境)移動應用 (一)JavaScript
- Liftoff:2020年移動應用程式趨勢報告
- Adjust最新報告:2021年第1季度移動應用增長31%
- 翻譯計劃 – 用 node.js 開發一個可互動的命令列應用Node.js命令列
- 【Python】Python利用有道翻譯開發API應用示例PythonAPI
- kurento 6.14.0文件翻譯第九章 編寫Kurento應用程式
- [翻譯] 使用JavaScript實現自己的PromisesJavaScriptPromise
- 移動應用效能優化優化
- 多翻譯引擎的程式
- Golang 編譯windows應用程式Golang編譯Windows
- 索尼正式釋出mocopiPC應用程式及移動端DataAnalyzer
- 用python實現簡單的線上翻譯程式Python