# 🏅 Day 17 - ref、reactive 本日開始會帶入一些和 Vue 結合的一些小練習,讓同學可以對如何將 TypeScript 導入到實際的開發上更有把握~ 延續昨日的每日任務內容,一樣會使用六角的 TodoList API 進行練習! 1. API 網址:https://todolist-api.hexschool.io/ 2. API 文件:https://todolist-api.hexschool.io/doc/ ## ref Vue 當中的 `ref` 方法是 Composition API 中的核心功能之一,可以用來建立可互動的參考對象或存取 DOM 元素。透過 `ref()` 來包裝基本型別可以讓資料在變動時自動觸發畫面更新,並且能夠透過 `.value` 讀取或修改內容。 至於 `ref` 和 TypeScript 的互相搭配則可以用下面幾種不同的方式來表示: ```tsx // 對於基本型別的 ref,可以透過 Generic 的方式來將型別給帶入到裡面 const name = ref<string>("") // 不過像上面的例子有初始值給定的狀況下,也可以省略型別的指定 (類似型別推斷的效果) const amount = ref(0) // 一般來說比較必要帶入型別的情況會是對於陣列或是 DOM 元素的 ref const numArr = ref<number[]>([]) const addressInput = ref<HTMLInputElement | null>(null) ``` ## reactive 而另一種 `reactive` 方法則主要常用於建立物件,在其中的屬性值產生變動時自動觸發畫面更新,適合處理結構化資料,例如表單或狀態物件等。它與 `ref` 的差異在於 `reactive` 可以直接操作物件當中的屬性屬性,不需要再透過 `.value` 來存取內容。 在 TypeScript 的搭配上,則可以直接利用類似型別註釋的方式來為 `reactive` 加上型別定義: ```tsx type UserInfo = { name: string; email: string; age: number; } const userInfo: UserInfo = reactive({ name: "", email: "", age: 0 }) ``` ## 實作時間! 經過昨天將通用的 API 請求方法設計完成並套用到 TodoList API 後,接下來就可以將設計好的方法在實際的元件裡面來使用了!本日主要會圍繞在使用者相關的功能來進行練習,包含註冊、登入和顯示登入狀態 (nickname) 的實作。 下方為參考的簡易 template 範例,在練習時可以直接複製到專案當中來使用,或是也可以自行設計版面的呈現方式~ ```html <template> <section> <!-- TODO:註冊區塊 --> <div> <h2>註冊帳號</h2> <form class="form"> <div> <label for="email">Email: </label> <input type="email" id="register-email" name="email" required /> </div> <div> <label for="password">Password: </label> <input type="password" id="register-password" name="password" required /> </div> <div> <label for="nickname">Nickname: </label> <input type="text" id="nickname" name="nickname" required /> </div> <button type="submit">註冊</button> </form> </div> <!-- TODO:登入區塊 --> <div> <h2>登入帳號</h2> <form class="form"> <div> <label for="email">Email: </label> <input type="email" id="login-email" name="email" required /> </div> <div> <label for="password">Password: </label> <input type="password" id="login-password" name="password" required /> </div> <button type="submit">登入</button> </form> </div> <!-- TODO:顯示登入狀態 --> <h2>{{ username ? "Hello " + username : "未登入" }}</h2> </section> </template> ``` 請實作該元件的 `<script>`,並且適當的調整 template 內容 (通常是在互動欄位中加入綁定函式等設定),透過串接 API 來完成使用者註冊、登入以及狀態的顯示。 另外一點需要注意的是,在引入 TypeScript 時,需要在 Vue 檔案中的 `script` 標籤內加入 `lang="ts"` ```javascript <script setup lang="ts"> const username = ref("") // TODO: 可以利用 ref 或 reactive 來處理表單資料的控制, // 並串接到 TodoList API 來實現註冊、登入的功能 // ... </script> ``` <!-- 參考範例: type SignupRequest = { email: string; password: string; nickname: string; }; type SigninRequest = Omit<SignupRequest, "nickname">; const signupData: SignupRequest = reactive({ email: '', password: '', nickname: '', }); const signinData: SigninRequest = reactive({ email: '', password: '', }); // 此處需將 signupData 和 signinData 的值綁定到表單的欄位中,例如: // <input v-model="signupData.email" type="email" id="register-email" name="email" required /> const submitRegister = async () => { const response = await register(signupData); console.log(response); }; const submitLogin = async () => { const response = await login(signinData); console.log(response); localStorage.setItem('token', response.token); username.value = response.nickname; }; -->