昨天用了 Cursor 幫我們寫了註冊頁面,各位應該有體驗到AI的強大了吧。今天我們要使用 UI Library 來把我們畫面美化。除了美化以外最大的原因是因為也可以省掉一些自己刻元件的時間。
UI Library(使用者介面函式庫)是一組預定義的元件和工具,專門為了讓開發者更快速地設計網頁或應用程式的使用者介面(UI)。它通常包含多種常見的介面元素,例如按鈕、表單、卡片、導航欄等,讓開發者可以直接使用這些已設計好的元件,而不必從頭開始造輪子。
優點
缺點
UI Library 是專門為了簡化和加速前端開發的工具,幫助開發者輕鬆打造現代化的應用介面,並確保設計的一致性。整體而言我覺得如果不是太獨特的設計,建議先使用UI套件會比較快。
以下為常見的 UI Library,通常就選自己習慣的喜歡的就好了。但如果上班,就只能選和團隊一樣的用。
React UI Library
名稱 | 簡介 | 官方連結 |
---|---|---|
Ant Design | 豐富的元件和設計規範,適合企業應用和後台系統。 | Ant Design |
Material UI (MUI) | 基於 Google Material Design,適合現代化且一致的介面。 | Material UI |
Chakra UI | 強調易用性與可擴展性,提供簡單的 API 和自定義樣式。 | Chakra UI |
Blueprint | 針對資料密集型應用,提供精細控制與豐富介面元件。 | Blueprint |
Semantic UI React | 基於自然語言設計的元件,簡單易用,適合快速上手。 | Semantic UI React |
React Bootstrap | 基於 Bootstrap,為 React 應用提供靈活、響應式的前端設計框架。 | React Bootstrap |
React Native UI Library
名稱 | 簡介 | 官方連結 |
---|---|---|
NativeBase | 跨平台支援,提供跨 iOS 和 Android 的元件,易於定制和擴展。 | NativeBase |
React Native Elements | 提供通用的 React Native 元件,簡單易上手,適合快速構建應用 UI。 | React Native Elements |
React Native Paper | 遵循 Material Design 標準,適合統一設計語言的應用。 | React Native Paper |
Shoutem UI | 多樣的預設樣式和元件,適合打造漂亮且一致的應用介面。 | Shoutem UI |
Teaset | 中國開發者常用的簡潔實用的元件庫,適合快速開發行動應用。 | Teaset |
我們這次專案選用 native-base ,我一開始是想找 Bootstrap 但我發現 RN 好像沒有,就只好找一個看起來比較好用的來用。
native-base 我發現他除了在 RN上可以用,網頁好像也可以用。這樣學起來不虧,等於又多會一個 UI Libarary。所以我就選用這個了。
那就讓我們開始吧!
起手式一樣,先在 Cursor 的聊天室提出問題請他協助。
我想 使用 native-base 這個套件幫我改寫一下登入頁面
Cursor:
要使用 native-base
套件來改寫你的登入頁面,你需要先安裝 native-base
。可以使用以下命令來安裝:
npm install native-base
接下來,這是改寫後的登入頁面代碼:
import React, { useState } from 'react';
import { NativeBaseProvider, Box, Input, Button, Text } from 'native-base';
const Login = () => {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const handleLogin = () => {
console.log('登入中...', { username, password });
};
return (
<NativeBaseProvider>
<Box flex={1} justifyContent="center" padding={4}>
<Text fontSize="2xl" textAlign="center" marginBottom={4}>登入</Text>
<Input
placeholder="用戶名"
value={username}
onChangeText={setUsername}
marginBottom={3}
/>
<Input
placeholder="密碼"
type="password"
value={password}
onChangeText={setPassword}
marginBottom={3}
/>
<Button onPress={handleLogin}>
登入
</Button>
</Box>
</NativeBaseProvider>
);
};
export default Login;
我們可以點擊 Cursor 給你的回應上面的 Run,會自己幫你在終端機下指令。
下完指令後看模擬機會發現錯誤,壞掉了。這時候我們看一下終端機是什麼問題。看起來像是少了 react-native-safe-area-contex 這個套件。通常少了套件,在終端機下指令
yarn add react-native-safe-area-contex
這樣就可以安裝缺少的套件了。
再來我們可以看到,還是錯誤,看起來一樣只是缺少套件而已。不怕再操作一次。
yarn add react-native-svg
誒,終端機沒錯誤但模擬機還是錯誤。怎麼辦。其實真的沒辦法的話,建議還是要看一下官方文件。因為有時候問 GPT會亂回你,反而會花更多時間都解決不了。
看一下官方文件 Existing Project 這邊,一開始就是 安裝相依套件(Install dependencies) 這邊前面的步驟我們做過了,不過要再做一次也可以。
yarn add native-base react-native-svg@12.1.1 react-native-safe-area-context@3.3.2
再來是 Run pod install ,原來是少了安裝 ios的套件。跟著指令做一次。
cd ios/
pod install
接下來就可以看到登入頁面了!看起來好像差不多,但按鈕變得不一樣了。我們就可以開始使用 native-base 的 UI Library了。
今天我們再來做一個註冊頁面吧。老樣子一樣請 Cursor幫我們做。
我覺得很棒 那我現在想要有註冊頁面,如果再畫面上面放一個註冊頁面的按鈕,註冊的話需要打 使用者名字 信箱 密碼 確認密碼 如果不想註冊了也可以回到註冊頁面
適當的讚美一下 AI也是必須的。
Cursor:
要新增註冊頁面並在登入頁面上放置一個按鈕來切換到註冊頁面,你可以按照以下步驟進行:
以下是更新後的代碼:
import React, { useState } from 'react';
import { NativeBaseProvider, Box, Input, Button, Text } from 'native-base';
const Register = ({ onBack }) => {
const [username, setUsername] = useState('');
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [confirmPassword, setConfirmPassword] = useState('');
const handleRegister = () => {
console.log('註冊中...', { username, email, password, confirmPassword });
};
return (
<NativeBaseProvider>
<Box flex={1} justifyContent="center" padding={4}>
<Text fontSize="2xl" textAlign="center" marginBottom={4}>註冊</Text>
<Input
placeholder="使用者名字"
value={username}
onChangeText={setUsername}
marginBottom={3}
/>
<Input
placeholder="信箱"
value={email}
onChangeText={setEmail}
marginBottom={3}
/>
<Input
placeholder="密碼"
type="password"
value={password}
onChangeText={setPassword}
marginBottom={3}
/>
<Input
placeholder="確認密碼"
type="password"
value={confirmPassword}
onChangeText={setConfirmPassword}
marginBottom={3}
/>
<Button onPress={handleRegister}>
註冊
</Button>
<Button onPress={onBack} marginTop={3}>
返回登入
</Button>
</Box>
</NativeBaseProvider>
);
};
export default Register;
import React, { useState } from 'react';
import Login from './components/Login';
import Register from './components/Register';
import { NativeBaseProvider } from 'native-base';
const App = () => {
const [isRegistering, setIsRegistering] = useState(false);
return (
<NativeBaseProvider>
{isRegistering ? (
<Register onBack={() => setIsRegistering(false)} />
) : (
<Login onRegister={() => setIsRegistering(true)} />
)}
</NativeBaseProvider>
);
};
export default App;
import React, { useState } from 'react';
import { NativeBaseProvider, Box, Input, Button, Text } from 'native-base';
const Login = ({ onRegister }) => {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const handleLogin = () => {
console.log('登入中...', { username, password });
};
return (
<Box flex={1} justifyContent="center" padding={4}>
<Text fontSize="2xl" textAlign="center" marginBottom={4}>登入</Text>
<Input
placeholder="用戶名"
value={username}
onChangeText={setUsername}
marginBottom={3}
/>
<Input
placeholder="密碼"
type="password"
value={password}
onChangeText={setPassword}
marginBottom={3}
/>
<Button onPress={handleLogin}>
登入
</Button>
<Button onPress={onRegister} marginTop={3}>
註冊
</Button>
</Box>
);
};
export default Login;
說明
這樣就完成了登入和註冊頁面的切換功能!
接著看我們的模擬機,登入頁面下面多了一個註冊按鈕。點下去後會到註冊頁面,註冊頁面下面還有返回登入按鈕。確實符合我們的需求。
登入頁面 | 註冊頁面 |
APP.tsx
.....
{isRegistering ? (
<Register onBack={() => setIsRegistering(false)} />
) : (
<Login onRegister={() => setIsRegistering(true)} />
)}
....
通常我們再處理不同頁面的切換不會用一個變數的 boolean直來切換,畢竟以後不會只有兩頁切換。通常會使用Router的形式來做切換。
Router 的概念是指在應用程式中負責管理和控制不同 URL 對應的頁面或元件,讓使用者能夠在應用中進行不同路徑的導航。
上面提到頁面的切分應該要使用 Router。一樣請 AI 幫我們修改
我想把不同的頁面變成有 router 的概念切換,因為之後會有更多頁面
Curosr:
要在 React Native 中實現路由功能,你可以使用 react-navigation 套件。這樣可以方便地在不同頁面之間進行切換。以下是如何設置和使用 react-navigation 的步驟:
首先,安裝 react-navigation 和必要的依賴:
npm install @react-navigation/native @react-navigation/native-stack
npm install react-native-gesture-handler react-native-reanimated react-native-screens react-native-safe-area-context @react-native-community/masked-view
在你的 App.tsx 中設置導航容器和堆疊導航:
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import Login from './components/Login';
import Register from './components/Register';
import { NativeBaseProvider } from 'native-base';
const Stack = createNativeStackNavigator();
const App = () => {
return (
<NativeBaseProvider>
<NavigationContainer>
<Stack.Navigator initialRouteName="Login">
<Stack.Screen name="Login" component={Login} />
<Stack.Screen name="Register" component={Register} />
</Stack.Navigator>
</NavigationContainer>
</NativeBaseProvider>
);
};
export default App;
在 Login.tsx 和 Register.tsx 中,使用 navigation 來切換頁面。
import React, { useState } from 'react';
import { NativeBaseProvider, Box, Input, Button, Text } from 'native-base';
const Login = ({ navigation }) => {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const handleLogin = () => {
console.log('登入中...', { username, password });
};
return (
<Box flex={1} justifyContent="center" padding={4}>
<Text fontSize="2xl" textAlign="center" marginBottom={4}>登入</Text>
<Input
placeholder="用戶名"
value={username}
onChangeText={setUsername}
marginBottom={3}
/>
<Input
placeholder="密碼"
type="password"
value={password}
onChangeText={setPassword}
marginBottom={3}
/>
<Button onPress={handleLogin}>
登入
</Button>
<Button onPress={() => navigation.navigate('Register')} marginTop={3}>
註冊
</Button>
</Box>
);
};
export default Login;
import React, { useState } from 'react';
import { NativeBaseProvider, Box, Input, Button, Text } from 'native-base';
import { Alert } from 'react-native';
const Register = ({ navigation }) => {
const [username, setUsername] = useState('');
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [confirmPassword, setConfirmPassword] = useState('');
const [error, setError] = useState('');
const handleRegister = () => {
setError('');
if (!username || !email || !password || !confirmPassword) {
setError('所有欄位都是必填的');
return;
}
if (password !== confirmPassword) {
setError('密碼和確認密碼不一致');
return;
}
Alert.alert('註冊成功', '您已成功註冊!', [{ text: '確定', onPress: () => navigation.navigate('Login') }]);
};
return (
<NativeBaseProvider>
<Box flex={1} justifyContent="center" padding={4}>
<Text fontSize="2xl" textAlign="center" marginBottom={4}>註冊</Text>
{error ? <Text color="red.500" textAlign="center" marginBottom={3}>{error}</Text> : null}
<Input
placeholder="使用者名字"
value={username}
onChangeText={setUsername}
marginBottom={3}
/>
<Input
placeholder="信箱"
value={email}
onChangeText={setEmail}
marginBottom={3}
/>
<Input
placeholder="密碼"
type="password"
value={password}
onChangeText={setPassword}
marginBottom={3}
/>
<Input
placeholder="確認密碼"
type="password"
value={confirmPassword}
onChangeText={setConfirmPassword}
marginBottom={3}
/>
<Button onPress={handleRegister}>
註冊
</Button>
<Button onPress={() => navigation.navigate('Login')} marginTop={3}>
返回登入
</Button>
</Box>
</NativeBaseProvider>
);
};
export default Register;
雖然畫面看起來和上一步一樣,但不一樣的點是因為程式的寫法。在 Stack.Screen 這邊就可以再加上其他頁面加上去。
const App = () => {
return (
<NativeBaseProvider>
<NavigationContainer>
<Stack.Navigator initialRouteName="Login">
<Stack.Screen name="Login" component={Login} />
<Stack.Screen name="Register" component={Register} />
</Stack.Navigator>
</NavigationContainer>
</NativeBaseProvider>
);
};
切換導航頁面的時候可以用 navigation.navigate('Login')
,像這樣就是回到登入頁面。
<Button onPress={() => navigation.navigate('Login')} marginTop={3}>
返回登入
</Button>
做了註冊頁面,登入頁面。我們來做一下首頁吧。登入後的首頁。
要怎麼做首頁,其實除了用打字的以外還可以直接把圖片貼上去給Cursor請他幫你做出你想要的樣子。我們可以來把之前 Figma的圖把他貼上去請他照著做。
幫我加上一頁 Homepage,希望可以照上圖的設計。先假設登入後會到這頁。然後使用 native-base的套件實作。謝謝
Cursor:
要在你的 React Native 應用中添加一個首頁(Homepage),可以按照以下步驟進行。這個頁面將使用 NativeBase 套件來實現,並假設用戶在登入後會導航到這個頁面。
首先,創建一個新的檔案 Homepage.tsx
,然後在這個檔案中實作首頁的設計。接著,更新 App.tsx
以包含這個新的頁面。
Homepage.tsx
在 components
資料夾中創建一個新的檔案 Homepage.tsx
,並添加以下代碼:
import React from 'react';
import { Box, Button, Text } from 'native-base';
const Homepage = ({ navigation }) => {
return (
<Box flex={1} padding={4} justifyContent="center" alignItems="center">
<Button width="100%" marginBottom={4} onPress={() => {/* Handle create report */}}>
Create a new report
</Button>
<Button width="100%" marginBottom={4} onPress={() => {/* Handle report list */}}>
Report list
</Button>
<Button width="100%" marginBottom={4} onPress={() => {/* Handle settings */}}>
Settings
</Button>
<Button width="100%" onPress={() => {/* Handle help & support */}}>
Help & Support
</Button>
</Box>
);
};
export default Homepage;
App.tsx
接下來,更新 App.tsx
以包含新的首頁組件:
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import Login from './components/Login';
import Register from './components/Register';
import Homepage from './components/Homepage'; // 引入 Homepage
import { NativeBaseProvider } from 'native-base';
const Stack = createNativeStackNavigator();
const App = () => {
return (
<NativeBaseProvider>
<NavigationContainer>
<Stack.Navigator initialRouteName="Login">
<Stack.Screen name="Login" component={Login} />
<Stack.Screen name="Register" component={Register} />
<Stack.Screen name="Homepage" component={Homepage} /> {/* 添加 Homepage */}
</Stack.Navigator>
</NavigationContainer>
</NativeBaseProvider>
);
};
export default App;
在 Login.tsx
中的 handleLogin
函數中,當用戶成功登入後,導航到首頁:
const handleLogin = () => {
console.log('登入中...', { username, password });
// 假設登入成功
navigation.navigate('Homepage'); // 導航到首頁
};
這樣就完成了首頁的設計和導航。當用戶登入後,將會看到你所提供的設計。
可以看到點擊登入後真的出現我們想要的四個按鈕的畫面,但排版不是我們想要的樣子。我們想要兩個兩個方塊上下排列。只好再和他溝通一次。
在溝通一次導正到我們想要的結果
我想要排版是 有四個正方形方塊,上面兩個 下面兩個 全部靠上對齊。
Cursor:
要實現四個正方形方塊的排版,上面兩個和下面兩個全部靠上對齊,可以使用 NativeBase
的 Box
和 Grid
組件來進行排版。以下是更新後的 Homepage.tsx
代碼:
Homepage.tsx
import React from 'react';
import { Box, Button, Text, VStack, HStack } from 'native-base';
const Homepage = ({ navigation }) => {
return (
<Box flex={1} padding={4} justifyContent="flex-start" alignItems="center">
<VStack space={4} width="100%">
<HStack space={4} width="100%" justifyContent="space-between">
<Button width="48%" onPress={() => {/* Handle create report */}}>
Create a new report
</Button>
<Button width="48%" onPress={() => {/* Handle report list */}}>
Report list
</Button>
</HStack>
<HStack space={4} width="100%" justifyContent="space-between">
<Button width="48%" onPress={() => {/* Handle settings */}}>
Settings
</Button>
<Button width="48%" onPress={() => {/* Handle help & support */}}>
Help & Support
</Button>
</HStack>
</VStack>
</Box>
);
};
export default Homepage;
這樣的排版會使得四個按鈕呈現為兩行,每行兩個,並且全部靠上對齊。
排版對了,但不是我們想要的正方形方塊,也是啦,比較窄的那種。不過沒關係,已經達成我們的需求了。
![[Pasted image 20240924164252.png]]
我們今天使用了 Cursor 幫我們使用 native-base 這個UI庫生成註冊頁面和修改了登入頁面,還有生成了登入後的首頁。
還請他加上了 Router的概念。
雖然我們只是和他提出需求後,套用程式碼檢視成果,發現現問題下一步修改。靠著這樣子的來回我們完成了我們的目標。
明天來整理一下今天用的東西吧。會用以外,也是要會懂使用的東西。因為總會遇到需要自己修改的時候。雖然我們目前還沒修改到一行程式碼。
又到了我們最後的工商時間啦~~~。Tom有在經營 Pocast,目前比較偏向職場類的閒聊,未來Podcast預計更新與程式軟體開發相關的主題。有興趣的朋友follow一下。
可以透過以下平台收聽: Apple podcast Spotify KKBOX
Linking Tree