[Tech] Vue Guideline (一)

Jack Huang
A Good Guy
Published in
7 min readJul 4, 2020
Vue 最早釋出於 2014 年 2 月,作者在 Hacker News、Echo JS 與 Reddit 的 JavaScript 版塊釋出最早的版本。一天之內,Vue 就登上這三個網站的首頁。

如果用一句話概括,我認為:前端最關鍵的任務就是將資料與狀態視覺化

早期的前後端分工大多是這樣的,那時前端的工作基本上被戲稱為是「頁面仔」,簡單來說就是負責切版,寫寫 HTML、CSS,偶而再加點 JavaScript 特效。然後就把頁面交給後端去套版,向後端拉拉資料顯示頁面就完工了。

而當我們把網頁作為應用程式時,實際上我們就是在操作資料與狀態本身,那些標籤、元件都只是表皮,我們就是把這些資料通通都「視覺化」。只是與傳統後端相比,前端除了要維護原本從後端取得的商業邏輯的狀態以外,還得多維護 UI 元件顯示邏輯的狀態

因此對於一名前端工程師而言,如果我們定義好畫面元素的顯示與操作邏輯後,剩下要關注的就只有狀態本身,如此一來可以大幅簡化前端工程師的工作 -> 而大部分主流的 MVVM 框架基本上也都遵循這個原則。

為什麼需要前端框架

而現在打開多數的求職網站會發現,大部分跟前端相關的職缺都會在求職條件或加分項目上提到目前的三大框架:React, Vue, Angular;或者也可以上 GitHub 搜尋 Awesome Javascript,可以看到目前所有前端的框架,而先前提到的三大框架在 GitHub 上也擁有驚人的星星數量。

雖然身為開發者本就該學習熱門的新技術以不被淘汰,但是重點是我們自身也必須釐清為什麼需要使用所謂的 framework 開發前端網頁

無框架開發

作為前端開發控制網頁的手段,開發者第一個要面臨的問題就是 DOM 的操作。在那個時期,每家瀏覽器對 JavaScript 的實作可以說是五花八門,其中最典型的例子就是「事件處理」。

在早期的 IE (其實也沒有那麼早,泛指 IE9 以前),事件綁定就分為 W3C DOM 標準的 addEventListener() 以及 IE 獨有的 attachEvent()。因此在當時前端工程師可能會透過 adapter pattern 來解決這種問題:

目前的解決方法看似沒有太大的疑慮,但是剛才問題的根本在於:每個前端工程師可能會採取不同的方式來解決不同瀏覽器實作的問題,因此一個問題會產生很多不同的解法。當一個問題沒辦法透過統一個規則或定義產生同一解法時容易導致前端工程師 co-work 整合的難度提昇,進而增加專案品質的下降。

這也就是為什麼在當時 jQuery 會如此興盛,即便是現在也還有人在使用,因為它做到了以下兩點:

  • jQuery 做到了弭平瀏覽器各種實作不同(例: XHR 差異的 ajax 函式),將複雜的瀏覽器差異邏輯判斷藏在套件中,讓開發者只需要專注在想實作的邏輯即可因而受到大部分前端工程師的青睞。
  • jQuery 其簡潔的語法、直覺好用的元素選取器,因此 jQuery 也同樣適合進行原型的快速產出。

框架或工具都是因應某個需要被解決的問題而生。

以上種種特色即使到 2020 的現在,開發者根據使用者行為靈活操作 DOM element 、專注在功能上的開發的 pattern 仍頗受歡迎,但是隨著專案的規模逐漸變大,僅僅使用 jQuery 這種 UI Library 會造成程式複雜度不斷上升,同時直接操作 DOM element 的缺陷也漸漸浮出檯面:

難以維護

在過去前端網頁開發中,即使採用 jQuery 這種 UI Library,在開發的過程中常常仍需要透過 JavaScript 處理互動的內容,因此導致 HTML, CSS, JavaScript 三者常常需要結合無法有效的分離,進而導致架構耦合度提高,程式碼管理困難。

效能低落

HTML 透過瀏覽器渲染畫面時同樣也存在渲染的生命週期:(對瀏覽器渲染原理有興趣的話可以看這篇

  1. 從 HTML 檔解析出 DOM Tree。
  2. 從 CSS 檔解析出 CSSOM Tree。
  3. 兩者疊加後產生 Render Tree。
  4. Reflow:計算出 Render Tree 上各個元素的物理屬性,如位置、大小、及是否看得見(visible)。
  5. Repaint:將計算結果轉為實際的像素,畫到畫面上。

然而當頁面邏輯常常直接操作 DOM element 會觸發整個 Reflow 以及 Repaint 的流程,如此一來,當網頁與使用者互動的元素多了,頻繁的觸發重複渲染會造成頁面效能的降低。

有框架開發

既然有前述的問題,自然有強者想要解決它,針對前面所描述的兩個問題,我們可以在更細部的去討論:

難以維護 -> 由資料決定畫面

因為 HTML, CSS, JavaScript 三者常常需要結合無法有效的分離最根本的原因在於:頁面結構不能單純靠 HTML 決定,每次的頁面更新需要透過 JavaScript 同步

先回想一般而言我們使用純 HTML, CSS, JavaScript 開發時,我們想要顯示一筆資料,可能會必須寫死在 HTML 的結構中:

而針對動態的資料,可能要透過 JavaScript 將資料動態塞入 DOM element 上:

因此在傳統的 HTML, CSS, JavaScript 的網頁開發上,常常會需要針對不同狀況執行 appendChild, remomveChild 等中間步驟來同步 UI 與資料。

但是今天如果我們採用 Vue 來寫,可能就會寫成下面這樣:

乍看之下兩種寫法好似相差無幾,但如果考慮到可讀性及後續的可維護性,相信大部分的人都能同意後者相對來說會比較容易閱讀及維護吧?透過 Vue 的寫法,讓頁面結構的部份仍然由 HTML 決定,並由資料來決定畫面該如何呈現,框架在底層幫你自動偵測資料變化更新 UI,讓 UI 變化有跡可循。

注意到關鍵了嗎?由資料決定畫面,這就是現代框架至關重要的核心概念:令資料從介面中抽取出來,每個畫面都是對資料處理過後的呈現

難以維護 -> 模組化 UI

一個網站中總是會有一些重複的 UI 元件,例如按鈕、輸入表單、表格或對話框等等,可能一個頁面中重複的元件超過數十個都不為過:在現代的框架中把這些重複出現的 UI 元件稱為組件(Component),每個組件內包含了組件自己需要用到的結構、樣式、邏輯,這樣一來,各組件只需要處理組件內的事,外部引用的組件來決定怎麼使用、提供什麼資料給組件,藉由簡單的切分權責,加上前述的由資料決定畫面,就能讓各個組件的任務單一,並且能被重複使用。

甚至現在有許多完成度很高的前端 UI 組件庫,讓開發者有如玩樂高一樣,能快速地用組件堆出想要的畫面,大幅度降低了組織畫面所需要的時間,讓工程師能更專注在處理商業邏輯上。

效能低落 -> Virtual DOM

Virtual DOM 是以 JavaScript 物件模擬特定 DOM 結構而產生的樹狀結構。

如同前述,在複雜的頁面中,如果頻繁透過操作 DOM 的方式改變畫面,可能會造成全頁面的 Reflow 及 Repaint;不過在使用框架時,開發者不用太擔心這個問題。

原因是在各主流框架的實作中,幾乎都包含了 Virtual Dom 的概念,也就是用 JavaScript 物件來表達當前的頁面結構;藉由與 UI 分離的資料及 Virtual Dom 之間的關係,當資料變動時,事先計算好這次畫面需要變動的地方,如此一來便能抵銷掉無意義的更動,並重複利用已存在的 DOM 元素;當真的要進行 DOM 更新時,也會一次將所有需要更新的局部組件更新,讓效能的耗損盡可能降低。

不過當然,Virtual DOM 變動的計算也是需要耗費運算資源的,若是過於簡單的專案,或是批次的大量修改,很有可能原生的寫法還比框架快上不少;有興趣深入理解可以參考這篇

有句話是說:每 18 至 24 個月,前端都會難一倍,現在還不趕快學學前端嗎?

--

--