[專案紀錄]自學 Vue3 一週內重構 FOODMATE 專案

Ivy Hung
5 min readAug 12, 2021
Github Repo
Live Demo

原本的專案採用 server-side render 的全端模式,著重在後端的 CRUD 操作, 畫面則使用 Handlebars 來製作。一開始都用同步的方式渲染畫面,但為了讓使用者有更好的體驗,部分功能像是按讚、收藏有使用 Axios 加上 Handlebars compile 來改寫,但這種方式有些缺點:

  • 需要撰寫額外的 script,
  • Compile 使用方式不直覺(但也因為這次的練習,我在後來的迷你電商專案有使用這種方式引入 email template 再傳送給顧客,讓程式碼看起來更乾淨了!)
  • 需要依賴 DOM 去抽換元件,

再加上剛好想要學習 Vue3,所以決定重構一個前後端分離版本的 SPA,讓後端專注在處理資料,前端使用 AJAX 技術向後端請求資料後渲染局部畫面,並升級 UI 提升使用者體驗。

Before & After

(畫面被壓縮了請見諒)

最能掌握和花最多時間的地方

整題來說 Vue3 的學習體驗非常好,將畫面切分成 components 除了更好管理外還能重複使用,Vue Router 的使用邏輯也很像 express.js 的路由,看資料在各種元件裡傳來傳去用 Vue devtools 來 debug 也很有趣,還可以使用 VueX 來集中管理使用者狀態讓每個元件都可以調用!

我對於將畫面切分為 components 、基礎 router 的使用和資料傳遞流程都能夠掌握,主要在兩個地方花了最多時間:

  1. 研究如何讓 router 使用 history 模式,並且避免重整頁面後找不到畫面的情況
  2. 使用 vee-validate 來驗證使用者在表單上輸入的資料

使用 History 模式的 Router

原本使用 hash 模式的 router 會在網址上呈現 # 的符號,讓網址改變時畫面不會重新載入,我為了移除 # 搜尋後發現原來有另一個 history 模式,但要使用 history 必須搭配後端 server 的支持,才不會造成當使用者直接輸入網址或重整頁面時出現找不到畫面的情況。

研究官網 HTML5 History Mode 的說明後發現,當使用者直接輸入網址或重整頁面時,會繞過 index.html 去查找相對應路由下的檔案,但因為是 SPA 所以會找不到。解決方式是在由 Node.js/Express 建立的伺服器中使用 connect-history-api-fallback 這個套件,當出現符合條件的 request 時會自動導向指定的 index.html 就可以解決問題了!

修改後網址終於不會有 # ,重新整理或直接輸入網址也不會找不到畫面了~

使用 Vee-validate 驗證表單資訊後如何上傳圖片

vee-validate 內建許多規則且可以客製化錯誤訊息,使用起來非常方便,官方文件也很好懂,可以呈現這種效果:

若使用者通過驗證 submit 表單時,會觸發一個 event 來向後端傳送表單資料,我主要是在需要上傳圖片的表單遇到問題。

原本在沒有使用 vee-validate 的時候是用 new FormData(event.target) 的方式透過 event.target 取得表單本身再轉換成 FormData 物件來傳送,後來改用 vee-validate 後卻出現上傳圖片後無法顯示的狀況!我透過幾個步驟找出問題並解決:

  • 先判斷資料通過驗證表示格式正確,
  • 去資料庫檢查發現沒有存入圖片 url
  • 在前後端資料傳入傳出的關鍵點都用 console.log() 印出來看看資料傳遞的變化
  • 發現驗證完觸發 event 後,傳入的參數會是一包物件,不能直接用原本的 event.target 去得表單本身
  • 研究傳入的物件中 image 值會是包含 File 陣列,必須把它解構後取出,再研究 FormData 建構子用 append 方法把 File 加入

最後把整理過後的 FormData 再傳給後端終於可以成功上傳啦~

最後理出邏輯的時候感覺很簡單,但當時半夜花了兩三個小時還解不出來,只好先去睡覺,沒想到一覺醒來重新思考後突然豁然開朗,十分鐘解決!

重構後的感想

看到畫面大整修的過程好療癒,不用一直重新渲染畫面的體驗真棒。

沒用過前端框架前覺得好多資料夾看起來很複雜,沒想到一試成主顧,分門別類得管理非常簡潔、優雅、好維護,也很喜歡用 router 還有思考資料怎麼在各個元件中傳遞,過程中碰到的困難讓我有機會研究官方文件,靠自己找出解法的瞬間真的很有成就感!

接下來會繼續研究怎麼修改畫面和加一些新功能,還有研究 composition API 的使用方式,有時間的話也想把之前全端專案重構一下。

--

--