在 Vue 中,一個元件通常是一個.vue檔案,並分成三個區塊:
<script setup lang="ts">
const title = 'Hello Vue'
</script>
<template>
<h1>{{ title }}</h1>
</template>
<style scoped>
h1 {
color: green;
}
</style>
<script>:邏輯<template>:畫面<style>:樣式當初一開始接觸 Vue 時,以這三個區塊將其區分開來,對我來說是個蠻友善的區別法,既好理解、容易上手,也相對直觀一些。
但轉換到 React 時,就沒有.vue這種固定的元件格式。React Component 通常是一個負責描述畫面的 JavaScript 或 TypeScript function:
// App.tsx
function App() {
return (
<div className="app">
<h1>Todo List</h1>
<TodoForm onAdd={addTodo} />
<TodoList
todos={todos}
onToggle={toggleTodo}
onDelete={deleteTodo}
/>
</div>
)
}
export default App
上面是 Todo List 專案中App.tsx的部分程式碼。App 是 Component 名稱,而return後面這段看起來很像 HTML 的語法稱為 JSX。
至於為什麼 HTML 可以寫進 JavaScript、{todos}又代表什麼,以及 JSX 有哪些語法規則,就留到 Day 06 再仔細研究。
一開始我還傻傻以為看到的那堆function就是Component,但事實當然並不會是那樣XD
所以我繼續慢慢的一點一點去仔細了解,翻了翻React官方文件後發現 React Component 有一個明確的命名規則:Component 名稱必須以大寫字母開頭(可以回頭看上面的舉例程式碼)。
當 React 看到<TodoList />時,會把它視為自訂 Component;而像<div>這種小寫名稱,則會被視為原生 HTML 元素。
不過,大寫開頭只是 Component 必要的命名規則,並不是所有大寫開頭的 function 都一定是 Component。
目前整理下來,我暫時先用以下幾個線索辨認 React Component:
<ComponentName />
例如:
// TodoList.tsx
function TodoList({ todos, onToggle, onDelete }: TodoListProps) {
if (todos.length === 0) {
return <p className="empty">目前沒有待辦事項,新增一筆看看吧!</p>
}
return (
<ul className="todo-list">
{todos.map((todo) => (
<TodoItem
key={todo.id}
todo={todo}
onToggle={onToggle}
onDelete={onDelete}
/>
))}
</ul>
)
}
export default TodoList
// App.tsx
<TodoList
todos={todos}
onToggle={toggleTodo}
onDelete={deleteTodo}
/>
在這段程式碼中:
function TodoList():定義一個 Componentreturn (...):回傳要顯示的畫面<TodoItem />:在TodoList裡使用另一個 Component<TodoList />:在App裡使用TodoList ComponentTodoList,而TodoList裡又使用了TodoItem。todos、onToggle與onDelete是如何傳遞資料的,之後認識 props 時再繼續了解。所以 React Component 應該可以先簡單理解成:
一個負責描述畫面,而且可以像自訂 HTML 標籤一樣使用的 function。
Vue 的話,就是開頭提到的三個區塊中的其中一個,也就是在 <style scoped> 裡編寫樣式。
而在我目前的 React 專案中,App.tsx 會引入 App.css:
// App.tsx
import './App.css'
function App() {
return (
<div className="app">
<h1>Todo List</h1>
</div>
)
}
/* App.css */
.app {
max-width: 480px;
margin: 60px auto;
padding: 24px;
font-family: system-ui, 'Segoe UI', Roboto, sans-serif;
}
h1 {
text-align: center;
margin-bottom: 24px;
}
目前的 React 專案中,可以看到用來放置樣式的App.css檔案,並在裡面編寫自訂的 CSS 規則。接著透過 import './App.css'將樣式引入App.tsx。
不過,React 本身其實沒有規定 CSS 一定要放在哪裡,將 Component 與 CSS 拆成不同檔案只是常見做法之一。
在 JSX 中替元素指定 CSS class 時,不是使用 HTML 的class,而是使用className,兩者在這裡的用途相同。
| Vue | React |
|---|---|
.vue |
.jsx或.tsx |
<template> |
return (...) 裡的 JSX |
{{ title }} |
{title} |
| Vue Component | 負責描述畫面的 function |
<TodoList /> |
<TodoList /> |
src/components |
src/components |
<style scoped> |
一般 CSS、CSS Modules 或其他樣式方案 |
.vue檔案src/components 是整理元件的常見方式,不是 React 的硬性規定<TodoList /> 這類標籤組合元件現在我知道 React Component 原來可以是一個 function,但return後面那段明明長得很像 HTML,為什麼可以直接寫在 JavaScript 裡?
下一篇 Day 06 繼續往下認識 JSX!
PS:因為目前還在剛接觸&學習階段,如果文章中有理解錯誤或不夠精確的地方,也歡迎各位前輩多多指教~!