---
# System prepended metadata

title: 第三週
tags: [2024 Vue 前端新手營 - Composition API]

---

本文件連結：https://hackmd.io/5yLsbZ7kSw-Qkp5pe_RZ1A

# 第三週

## 課前說明

- 課前影音 / 錄影回放：https://courses.hexschool.com/courses/enrolled/2574732
- 每日任務：Discord 上發布
- 討論頻道：https://discord.com/channels/801807326054055996/1258601572867379222
- 每週挑戰：
    - 一～三週：HackMD 上繳交
    - 最後一週作業：https://rpg.hexschool.com/#/training/12062289980134006991
- RPG 程式勇者：
    - 課程捷徑
    - 課程講義
    - 最後一週作業繳交
- 提醒老師錄影

### 額外課程介紹：
- JS 直播班：https://www.hexschool.com/courses/js-training.html
- JS&React 直播班：https://www.hexschool.com/courses/js-react-training.html

## 常見作業 QA

- axios Headers 加入方式
- Token 送出了什麼
- GitHub Pages 少見錯誤
- 發問方式導致他人難以理解

## **建立元件**

### 什麼是元件？

故事：漂亮阿姨電腦壞了，想請小明幫忙組一台新的

原價屋：https://www.coolpc.com.tw/evaluate.php

商場上有賣個是零件：

- CPU、記憶體、主機板、鍵盤、滑鼠 → 都是元件
- 主機板與 CPU 的關係 → 同廠牌的才能相容
    - Intel CPU 需對應 Intel 主機板
    - AMD CPU 需對應 AMD 主機板
- CPU 與 主機板的傳輸 （主機板與 CPU 的資料傳輸） → 元件資料傳輸，資料傳輸不會跨元件
    - 鍵盤插在 USB 孔上（鍵盤與主機板的資料傳輸）
    - 螢幕透過 HDMI 插在顯示卡上（螢幕與顯卡的傳輸）
    - 顯卡插在主機板上（顯卡與主機板的傳輸）

**為什麼要使用元件？**常見拆分原因：

- 程式碼太長
- 部分元件需要多次運用
- 邏輯拆分，不同的功能使用獨立的元件進行運作
- Vue Router 時，每個元件都是獨立頁面

### 元件建構起手式：

1. 建立新檔案
2. 加入 template，及基本 HTML 結構
3. import
4. 將它呈現在畫面上

### 註冊元件方法：

1. 區域註冊：實戰建議使用這種
2. 全域註冊：套件、Loading


**元件特性：**

1. 狀態獨立
2. 封裝
3. 可重複使用
4. Props

## 元件資料傳遞

為什麼要做資料傳遞
六角的框架直播班作品範例：https://works.hexschool.io/#/

- 兩大體系：全域傳遞、元件間傳遞
    - HTML 是兩者串接的橋樑


- 元件向內傳遞
    - 外到內：props
    - 使用方法：defineProps
    - 口訣：前內後外 - 前面是名稱，後面是值
    注意：
        - 單向數據流，內層不改外層資料
        - HTML 屬性一律是小寫
        - 該資料如果不存在，則可能會導致內層出錯

![空白](https://hackmd.io/_uploads/HJhyTX5q0.png)


使用範例：

```jsx
import { defineProps } from 'vue'

defineProps(['title', 'content'])
```

如果該值，需要在 script setup 中運用

```jsx
import { defineProps } from 'vue'

const props = defineProps(['title', 'content'])
console.log(props);
```

- 元件向外傳遞：
    - 內到外：emit （這是事件）
    - 口訣：前內後外 - 前面是內部觸發的事件，後是外部對應的函式

**使用範例：**

內層範例：

```jsx
const emit = defineEmits(['editText']); // 定義事件名稱
const innerText = ref('內層的文字')
const emitText = () => {
  emit('emitText', innerText.value); // 傳遞事件名稱, 參數
}
```

外層程式碼：

```html
<!-- 前內後外：前面是內部觸發的事件，後是外部對應的函式 -->
<Card
  @emitText="editText"
></Card>

<script setup>
import { ref } from 'vue'

const cardData = ref({
  title: '卡片標題',
})

const editText = (newTitle) => {
  cardData.value.title = newTitle
}
</script>
```

### **元件建構基本原則：**

1. 不要建構元件 → 先把功能寫出來再說
2. 不要把元件拆太細 → 等到程式碼太常再說

### 元件轉換原則

1. 先不要想著拆元件
2. 先不要急著拆元件
3. 試著拆元件，並確保功能與原本一致

- 下到上：$emit（托球）
    - 口訣：emit 推，外 methods 接收
    - 口訣：HTML 前內，後外

## 額外補充：

由 Props 傳入的值，當傳入的物件參考改變時，並不會套用新的值，如果要監聽外部傳入的值，可以使用到 watch 的方式。

```jsx
const props = defineProps('person');
watch(() => props.person, (newVal) => {
  name.value = newVal.name;
});

const name = ref(props?.person?.name); // 確保值會因為外部的物件變動時，持續進行替換
```

## 在 Vite 導入 Scss 服務


## 作業

【題目】： 餐點管理工具

作業使用者故事：

1. 點餐人員可以將左側的品項加入購物車
2. 點餐人員，可以刪除、調整購物車品項數量（Level 1, 2 可不做）
3. 點餐人員可加入備註
4. 點餐人員可以建立訂單

LV：
1. LV1. 僅將以上功能完成，不拆分成元件（可以**省略：刪除、調整數量的功能**）
2. LV2. 包含以上功能，至少額外拆分兩個元件
3. LV3. **不參考解答**製作菜單工具，不省略任何功能且至少包含額外三個元件（重複品項無法重複加入）

解答連結：

- 執行範例：https://www.casper.tw/2024-vue-homework/#/week3
- 原始碼：https://github.com/Wcc723/2024-vue-homework/blob/main/src/views/Week3View.vue
- 作業繳交連結：https://hackmd.io/nX7LspikSmmglEb1Hyu2IQ

### 預告

最終任務：

- 設計稿：https://www.figma.com/design/MFSk8P5jmmC2ns9V9YeCzM/TodoList?node-id=0-1&t=KzEgeE3s3r6JIPh6-1
- CSS 範例：https://codepen.io/hexschool/pen/qBzEMdm
- 同時挑戰證書任務：
    - [最終挑戰 - Todolist 新手證書任務](https://rpg.hexschool.com/#/tasks/12062289980169123704?preview=1)
    - [最終挑戰 - Todolist API 整合證書任務](https://rpg.hexschool.com/#/tasks/12062289980139618730?preview=1)
