Skip to content

Instantly share code, notes, and snippets.

@oomusou
Created February 20, 2019 14:35
Show Gist options
  • Save oomusou/b11183e44310378dfd435ad75266a427 to your computer and use it in GitHub Desktop.
Save oomusou/b11183e44310378dfd435ad75266a427 to your computer and use it in GitHub Desktop.

Functional Vue Architecture

Sam Xiao, Feb.18, 2019

Web 所面臨的挑戰

後端 MVC

約在 2015 年,主流的 Web 開發架構仍以後端 MVC 為主:

  1. PHP / Laravel
  2. Ruby / Ruby on Rails
  3. C# / .NET MVC
  4. Python / Django

這類都是 後端 以 MVC 為主,前端 以 jQuery / Ajax 為輔的架構。

這種架構有幾個挑戰:

  1. 有於重點在後端,時常必須換頁到後端去,使用者會明顯感受到網頁重新載入,視覺與使用感受較差
  2. 若想減少換頁到後端,就必須大量使用 jQuery / Ajax,則前端就會有大量 JavaScript
  3. 由於 JavaScript 缺乏 module 概念,實務上常常會看到上千行的 jQuery / JavaScript,導致維護困難
  4. 由於 jQuery / JavaScript 是躲在後端網頁內,因此大部分的 jQuery / JavaScript 都是由後端工程師撰寫,但由於 JavaScript 語言特性與後端語言明顯的差異,大部分後端工程師選擇逃避原生 JavaScript,而改用較容易的 jQuery,此時都是 Web 工程師都是 全端工程師
  5. 也由於使用 jQuery,導致大部分 全端工程師 並沒有深入研究 JavaScript,而是認為前端只是控制 HTML / DOM 而已,jQuery 足以,因此沒必要深入研究 JavaScript,導致一些 JavaScript 很重要的語言特性被忽略 (Higher Order Function、Closure、IIFE、Function Composition ...),其實這些 Functional 的語言特性,才是 JavaScript 的精華所在

前後端分離

2015 年開始有一些前端 framework 展露頭角,如 AngularJS、React:

  1. 後端只寫到 API,以 JSON 與前端溝通
  2. 顯示邏輯 寫在前端,而不是以 Presenter Pattern 寫在後端,因此沒有網頁重新載入,視覺與使用感受佳
  3. 前端開始有 Component 概念,也開始使用 ES6 (ECMAScript 2015) 的 module 概念,因此不再出現上千行 JavaScript,容易維護
  4. 由於使用 ECMAScript 2015,與原本 JavaScript 相比幾乎是全新語言,有學習門檻
  5. 前端技術發展迅速,開始有
    • Node.js 生態圈 (NPM、Yarn)
    • ECMAScript 每年會更新一版 (2015 ~2019)
    • Babel / Webpack 編譯打包技術 + ESLint (即使 JavaScript 不編譯,亦可享有編譯的優點)
    • 層出不窮的 library (RxJS、Ramda ...)
    • 層出不窮的 framework (Angular、React、Vue)
    • 由於前端技術爆炸,已經不再只有 jQuery,後端也要精通前端已經有難度,因此前後端開始分家,開始有所謂 前端工程師

前端的變革

相較於 jQuery、前端開始有了新的概念:

  1. Data Binding:傳統 jQuery 直接控制 DOM;現在前端改為控制 data,現在由 framework 處理 data 與 DOM 的改變
  2. Reactive Programming:傳統 jQuery 是根據 event 去做相對應的處理;現在將 event 視為 stream 處理 (RxJS)
  3. Functional Programming:由於 JavaScript 深具 Functional 語言特性 (以 Scheme 為原型),原本 OOP 的 MVC 架構蛻變為 FP 的 Pipeline (單向資料流) 架構 ( React 的 Redux、Vue 的 Vuex)
  4. Webpack Tree-shaking:由於 OOP 大量使用 field,導致 Tree-shaking 無法有效發揮,前端開始使用 FP 方式,以 function 取代 class,並使用 FP 的 Function Composition 取代 OOP 的 DI (Ramda)

可以發現前端的改變:

  1. 從控制 DOM 轉為控制 data,回歸程式設計的本質
  2. 由 Object Oriented Programming 改為 Functional Programming

Vue

Vue 吸取 React 與 Angular 的優點:

  1. 從 Angular 學到學習門檻較低的 HTML Template,而非 React 的 JSX
  2. 從 Angular 學到 directive 控制 HTML,而非 React 直接以 JavaScript 夾雜 HTML
  3. 從 React 學到 Component 概念,使得 顯示邏輯 得以模組化
  4. 從 React 學到 狀態管理 概念 (Redux) ,讓跨 component 的溝通更加簡單 (Vuex)
  5. Vue 前期學 Angular 較多,後期則明顯向 React 靠攏

儘管如此,Vue 也有自己的缺點:

  1. Vue 的 datacomputedpropsmethod ... 都必須靠 this 存取,這是一種具有 Side Effect 的寫法,且由於 this 的可變性,導致 Vue 重構的困難

  2. Vue 寫法多元,最原始寫法是一種依賴 this,很像 OOP 又不是 OOP 寫法,後來又開發出 class-component,這是正統 OOP 寫法,風格很像 Angular,但也由於太偏 OOP,導致大部分人寫 Vue 都使用 OOP 思維,而忘記 JavaScript 最重要的 Functional 特性 (Higher Order Function、Closure、IIFE、Function Composition ...)

Functional Vue

  • Vue 的 datacomputedpropsmethod 這些本質都是 function,不要將這些寫在 Option Object 內,而將所有的 function 拉出來,也由於看到的是一條條 function,不是 OOP 的 method,有助於發現重複的部分以 Higher Order Function 重構

  • 除了 HTML Data Binding 的資料放在 data 外,不要把 data 當成 OOP 的 field 使用,如此可避免使用 Side Effect 寫法,而改用 Pure Function 風格

  • 將資料從 data 搬到 Vuex 的 state,由於 stategettermutationaction 不使用 this,Vue 可徹底從 ES5 的 function 寫法解放,全面改用 ES6 的 Arrow Function

  • 也由於 stategettermutationaction 本質上都是 function,可以很容易抽成 Higher Order Function,也可以整合 Ramda / RxJS 這類 Functional Library,透過 Function Composition 產生 stategettermutationaction

  • 也由於所有的 function 都沒有 this,都是 Pure Function 沒有 Side Effect,因此很容易重構到適當 module,不必被 Vue 的 componentmixin 所綁架

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment