學習紀錄-Vue - The Complete Guide (incl. Router & Composition API)

已經很久沒有寫心得文了,趁這次剛好有機會碰到一個學習動機比較強烈的 moment,順便當成新年新希望之一,學習一下新購入的 Udemy 課程並記錄

因為章節很多,加上我覺得可能心得也會很簡單沒什麼好寫的,所以大概就是遵循之前 TDD 的學習方式,紀錄一下日期、感想即可。畢竟這篇文章沒有要闡述什麼東西,純粹就是用來鞭策自己的一個學習紀錄而已,對於其他人來說,大概也就像是一個課程開箱文的東西吧。

  • 課程資訊:Vue - The Complete Guide (incl. Router & Composition API)
  • 購入價格:NT:570(2023 過年特價期間)
  • 購入動機:對於Routing: Building "Multi-Page" Single Page ApplicationsVue & AuthenticationVue2 to Vue3 Migration這三個章節主題還蠻有興趣的
  • 對課程的期許:希望能了解一下這麼多人一致推薦點讚的課程,關於這三個主題有甚麼值得學習的重點
  • 對自己的期許:除了這三個主題以外,也順便從頭惡補一下基礎,順便重新培養一下學習的習慣,最近幾個月以來真的太放鬆了

Getting Started

2023-01-30: 大概所有的課程一開始都是比較介紹性質,所以也就輕鬆的大致瀏覽一下,比較有趣的部份是除了理論性的介紹以外,講師用一個簡單的範例來展示使用 Vue.js 前後的語法差異,對於開發而言應該很有感覺,將 Vue.js 的優點做了一個火力展示。相信沒有接觸過前端開發框架的人應該很震撼。

Basics & Core Concepts - DOM Interaction with Vue

2023-01-30: 這個章節大概的內容就是將比較實用的一些基本語法用範例來做教學,講的程度我覺得剛好,沒有非常細緻到你看不下去,也不會太省略,基本上該知道的基礎用法都有帶過一次,讓我覺得比較驚豔的是關於 v-on:input的部分,以前基礎知識不夠,只知道能這樣用 event$event,但卻不知道這個東西從哪裡來,看完之後才知道原來是內建的香草,而 Vue 也能用$event,這個其實以前都不是很清楚,透過這次釐清觀念,很開心。而且也因為對於 CSS 不熟悉,剛好這次的基礎中關於 style 的部分講師還透過好幾種寫法,逐漸演變的方式重構,真的是很不錯。

1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- 行內樣式 -->
<button class="demo" style="border-color: blue" @click="boxSelected"></button>
<!-- 綁定物件 -->
<button class="demo" :style="{ borderColor: 'blue' }" @click="boxSelected"></button>
<!-- 動態綁定 style -->
<button class="demo" :style="{ borderColor: selected ? 'blue' : 'red' }" @click="boxSelected"></button>
<!-- 動態綁定 class (CSS預先建立好 active 類別)-->
<button :class="selected ? 'demo active' : 'demo'" @click="boxSelected"></button>
<!-- 動態綁定 class 物件 -->
<button class="demo" :class="{active: selected}" @click="boxSelected"></button>
<button :class="{ demo:true, active: selected}" @click="boxSelected"></button>
<!-- 或者改用陣列綁定 -->
<button :class="['demo', {active:selected}]" @click="boxSelected"></button>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!-- 改成用計算屬性設定樣式 -->
<template>
<button class="demo" :class="boxCss" @click="boxSelected"></button>
</template>
<script>
export default {
data() {
return { selected: false }
},
computed: {
boxCss() {
return { active: this.selected }
},
},
method: {
boxSelected() {
this.selected = !this.selected
},
},
}
</script>

Rendering Conditional Content & Lists

2023-01-31: 這一章節重點在於如何根據所定義的條件來呈現不一樣的畫面,當然集合的列表呈現也是重點,今天嘗試了一下在解說需求的時候就先完成範例程式碼,最終與講師的比較,相差的不多,而在v-forkey屬性解說上,講得算清楚易懂,也順便重新溫習了一下這一段,還好沒有忘記,當然渲染列表最好還是有後端給予的unique key最方便。簡單來說如果只是用來作呈現,不會動態的去改變集合元素的話,我是覺得給不給 key 無所謂,反正渲染出來就都不會改變那就沒事;但如果是會動態改變元素的話,還是要確保 key 屬性是以唯一值代入的。

Course Project: The Monster Slayer Game

2023-01-31: 講師設計了一個簡單的小遊戲,透過這個需求來練習之前學習過的各種指令,整體來說是很有趣的,也透過一開始的需求說明,逐漸地釐清整體要做的事情有那些,有一點工作拆解的教學意思。使用到的東西都不難,而且也以實際需求帶出來用法,我是覺得這個小遊戲練習挺好的。

Vue: Behind the Scenes

2023-02-02: 這個章節講的東西都是一些你不知道但仍舊可以使用 vue,不過知道了之後對於 vue 的掌握度會更高一點,主要都是一些簡短但重要的觀念說明

  • Vue 的工作原理:
    • Vue 更新機制:透過 Proxy 來追蹤更新
    • Vue 的 Template 語法:透過模板語法,將 HTML 語法與方法、資料內聚在一起
    • Vue 透過 Virtual DOM 的比對來渲染修改過的頁面到實際 DOM
    • 支援 Fragments: 一個、或者掛載多個 Vue Instance
    • 透過 ref 讓 vue 訪問 DOM
  • Vue 生命週期:透過解說與實際操作中斷點展示生命週期過程中的 hook 與 UI 的狀態

Introducing Components

2023-02-02: 很多時候我們並沒有辦法透過到目前為止所學習到的東西來完成所有需求,就像是範例中的兩筆、或多筆資料呈現,如果要針對他做更精細的控制,就會碰上每一筆資料各自的狀態處理問題;而解決辦法就是封裝成一個 component,讓每個元件各自管理它們自己的狀態,當然到目前為止還沒有學到 SFC 與 props 等等,所以這個章節也只是簡單的帶出來問題與解決方案,後續還有一些基礎知識要補

Moving to a Better Development Setup & Workflow with the Vue CLI

2023-02-02:在這個章節開頭,重溫了一下之前的開發方式所遇到的問題,在改善開發流程的部分,使用了 vue cli 來解決先前碰到的問題,也因此開始接觸到當前流行的前端開發方式。影片中解說了 vue cli 的預設範本以及開發階段工作流程說明,其實也就是跟後端編譯式語言一樣,我們所撰寫的代碼不能直接被瀏覽器識別,需要先經過前端編譯的步驟,將其轉換為瀏覽器支援的語法後才能使用,這些東西 vue cli 都已經做好了,能夠在專案開始的時候省去很多設定的繁瑣作業,節省很多時間。當然開發工具也需要能夠支援 SFC 語法,這邊則是透過 VSCode plugin Vetur 來獲得 vue SFC 的 highlight 支援。當這些基礎的工作都準備完成之後,就可以著手開發新專案了

接下來的練習,則是從一個空白的專案開始,從安裝依賴項目,執行開發伺服器,同時編寫第一個 Vue SFC,熟悉一下開發的流程,並完成一個簡單的元件

當然隨著工具的演進,現在也可以使用npm init vue以及 VSCode 套件Volar來替換

Component Communication

2023-02-06: 關於組件之間的資料傳遞,基本的解決方案都是透過 props$emit 直接傳遞數據或方法,在這個章節以一個簡單的範例來解說,也補充了props,$emit定義的方式,便於偵錯。像是下面這樣的方式

1
2
3
4
5
6
7
8
9
10
11
12
13
props:{
username:{
type:String,
default:'noname'
}
},
emits:{
'toggle-favorite': function(id) {
if (id) return true
console.warning('id is missing')
return false
}
}

若是有資料要從父組件,往下要傳遞多個子組件,一路傳遞到最底層,中間若是都用 props 來層層傳遞就會很多餘,因此可以改用 provideinject,不論是資料或函式方法都可以透過這樣的方式傳遞給最底層元件,對於程式碼的整潔有很大幫助,基本上透過這樣的方式大致上就能夠處理好組件資料傳遞的問題了。在講師提供的教學範例中,所有的示範都遵循著一個規則:根組件提供資料,子組件使用資料

Diving Deeper Into Components

2023-02-06: 在先前的章節中,程式碼雖然可以運作,但若是在比較大型一點點的應用程式之內,就有一些議題值得思考及關注,講師又用了另外一個例子來解釋這一切,包含了

  1. 組件的註冊方式: 全域註冊或是在組件內引用其他組件,基本上一些屬於樣式的東西全站都會用到,所以樣式組件應該會是全域註冊
  2. 限縮樣式的有效範圍: style scoped
  3. 簡介slotnamed slot的使用方式
  4. 動態組件相關:dynamic component、keep-alive
  5. teleport標籤,可用於改變輸出的 HTML 位置
  6. 簡介了一下檔案命名及目錄存放的建議

在這邊講師重構範例中有一段是因為想要消除重複的 css 樣式而建立了一個 BaseCard 的組件,這是我沒想過的,可能是因為我完全不碰 CSS 所以對於這部分敏感度很低,但是經過示範後,才發現這樣的做法的確可以讓我目前專案很多東西都更簡潔;而要注意的地方是原先的樣式,因為作用域的關係也要隨之搬移到 BaseCard組件內,這樣可以避免在元件內宣告全域樣式從而影響到別的地方。

另外由於可以透過 $slot.header 檢查上層元件是否有傳入 header 的 slot 內容,因此也可以用下面的技巧來渲染輸出結果

1
2
3
4
5
6
7
8
<template>
<div>
<header v-if="$slots.header">
<slot name="header"> </slot>
</header>
<slot></slot>
</div>
</template>

而在這邊還有更重要也是非常實用的一個技巧,那就是透過 slot 由父組件傳遞內容給子組件的同時,在父組件使用的資料是子組件提供的,這個觀念就是scoped slot,意思就是讓這個 slot 在父、子組件之間的 scoped 去共享資料,範例如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- 父組件:透過 slotProps 取得 scoped slot 所綁定的所有資料-->
<course-goals>
<template #default="slotProps">
<h2>{{ slotProps.item }} - {{ slotProps.anotherProp }}</h2>
</template>
</course-goals>

<!-- 子組件:宣告 slot 的同時綁定資料提供給 scoped slot -->
<template>
<ul>
<li v-for="goal in goals" :key="goal">
<slot :item="goal" another-prop="something"></slot>
</li>
</ul>
</template>

更細節的部份可以看一下 Vue 官網Slots說明會更清晰一點

連續幾個範例下來,我發現講師在設計課程的時候是有用心過的,可以注意到每次透過解說範例來教學新的指令的時候,都是伴隨著需求而直觀的寫出第一版,隨後學習到更多東西,或者是碰到問題後,再接著用別的方式改善,其實就是一直在針對程式碼進行重構,而在重構過程中,也都在為了消除重複,不管是程式碼、HTML 或者是樣式,從而使最終程式碼變得更為清晰易懂

Course Project: The Learning Resources App

2023-02-06:之前學習過的東西,在這個章節都實際演練一次加深印象,同時在過程中伴隨著講解說明,將組件的設計概念、目錄配置及考量的原因都一併解說,含金量很高。這邊會從 components 目錄開始,底下再開始細分UI(帶入 base 組件概念)、layouts(共用布局)以及應用程式本身功能的目錄;同時也依據各種組件,決定採用Global或者是Local引用,順便帶了一下命名規則概念,這些都是重溫先前學習過的東西,相信對於不是一開始就學習前端的人會有所幫助

從頭到尾跟著做一遍,的確也發現了許多地方以為自己知道,但實戰總會卡住想一下的情況,沒有辦法,多練習幾次就知道了,這一章節的練習對於學習效果的確是不錯的

Forms

2023-02-07:關於表單的部分專門弄了一個章節來解說,其實也就是把 vue 綁定各種表單元素的東西做過一次,一些比較容易錯誤的地方也有說明,至少看完這章節能夠將表單資料記錄下來就是了,至於驗證提示的方式,也有稍微示範一下,比較特別的是最後有補充如何自訂表單客製化元件,是個不錯的啟發。

Sending Http Requests

2023-02-07:這章節很有意思,除了教怎麼發出請求獲取資料以外,當然也帶了一下 firebase,範例透過一個簡單的 local 資料處理範例,展示了新增、讀取的功能,一步步地轉換到將資料儲存於後端,有意思的點在於在跟後端互動的過程不一定是順利的,又或者是為了顧及使用者體驗,所以需要在畫面上有一些回饋,因此針對這些情況作了一些例外處理,這就是實務上一定會碰到的事情

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
fetch("https://xxxxxxx.firebaseio.com/surveys.json", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(sendData),
})
.then((response) => {
if (response.ok) {
// ...
} else {
// server 端錯誤
throw new Error("Could not save data!")
}
})
.catch((error) => {
this.error = error.message
})

Routing: Building “Multi-Page” Single Page Applications

2023-02-07: 這個章節主要解說 SPA 的概念及實作,重點會放在路由的部分,由於涉及的東西真的很多,只看一次應該會是有點印象而已,自己之後可能會再參照官網說明或者是再多看幾次。除了基本的路由設定以外,還包含了動態路由參數、將動態路由參數改用 props 傳遞給元件、巢狀路由等等,講師在示範的時候我覺得蠻詳細的,路由順序設定的部分也特別提醒了路由比對的小問題及解決方案,算是非常貼心了

Animations & Transitions

TBD

Vuex

TBD

Main Project: “Find a Coach” Web App

TBD

Vue & Authentication

TBD

Optimizing & Deploying Vue Apps

TBD

The Composition API - Replacing the Options API

TBD

Reusing Functionality: Mixins & Custom Composition Functions

TBD

Roundup & Next Steps

TBD

Vue2 to Vue3 Migration

TBD

Learn Vue2 | Old Course Content

這個章節主要是釋出一些舊的課程資源,原因是當初課程是為了 Vue2 所錄製的,後來 Vue3 發佈之後,講師也將課程全部重新錄製為 Vue3 版本。若是想要訪問原始課程內容學習 Vue2 的話,在這邊可以透過講師提供的原始影片及代碼學習,影片品質很不錯,可惜的是沒有提供任何語系的字幕檔案