雜談 Web 前端編程範式
題圖來自互聯網
前言
放假在家的時間裡稍微研究了一下 Polymer,這算是第一次正式體驗 Web Components 技術了。它給我我的第一印象很好,開發體驗很不錯,我覺得前端開發就應該是這樣。所以這篇文章我就隨便談談我對前端幾種技術的看法。
近年來前端技術應該算是爆髮式地增長,從 Node.js 開始,前端似乎像是被玩壞了,各種框架,各種開發模式……很多人甚至羞於談 jQuery,他們認為一個前端項目不使用 React、Angular 都不算搞開發。在接觸 Polymer 之前,所有前端框架中,我最喜歡的是 React,它一方面不像 Angular 那樣做到一站式的「捆綁銷售」,讓我能對技術棧有自己的選擇;另一方面,Virtual DOM 的引入使得其渲染性能相比其他框架確實有很大的提升。
以 React 為代表的 Functional Programming
雖然 React 官方並沒有強制開發者使用函數式範式來做開發,但不管是從實際應用還是 React 的低層實現來講,函數式是 React 的最佳食用方法,React 是典型的數據驅動視圖,就拿下面的例子來講:
const Greeting = (props) => {n return (n <div>n <h1>Hello, {props.name}</h1>n </div>n );n}n
React 的每個組件說白了就是一個函數,從參數中獲取數據,一級一級完成全部的渲染,有的複雜一些的組件可能會有自己的 state,不過如果項目中使用了 Redux 等 FLUX 模式的庫,state 也可以完全省略。但從根本上,React 就是做了一件高效地將數據轉換為視圖這樣的工作,視圖就是數據的一種體現。包括 Facebook 官方推薦使用 Immutable.js 來管理數據,目的就是輔助 React 更高效的渲染,通過 Immutable 的冪等檢測來決定究竟 DOM 樹中的哪些節點需要被重新渲染。同時 Immutable 也是函數式的重要基礎,每次操作都會產生一個新的、完全獨立的 state 對象,用這個 state 來渲染 DOM 樹,並且還能輕鬆獲得 Undo-Redo 和時間旅行的功能加成。Redux 作為狀態管理的一種解決方案,很好地協調了 Action、Store、Reducer 之間的關係,很多人問 Redux 到底是什麼,它其實就是一個函數:
function Redux(initialState, reducer) {n var store = { state: initialState };n store.dispatch = (action) => {n store.state = reducer(store.state, action);n // notify subscribers...n }n return store;n}n
你的任務就是確保 state 的不可變性就可以了,reducer 每次必須要產生一個不同的 state 對象,剛才提到的 Immutable.js 是一種途徑,ES6 也有很好的語法糖可以做到這一點。
講起來 ClojureScript 更適合這種開發模式:
(defn lister [items]n [:uln (for [item items]n ^{:key item} [:li "Item " item])])nn(defn lister-user []n [:divn "Here is a list:"n [lister (range 3)]])n
語言自身的特性使得我們也不用為對象的 Immutability 而煩惱。
但是用函數式的觀點去構建用戶界面我一直不太贊同,隨著項目的不斷擴大,應用狀態的管理就會愈發困難,並不是所有人都只需要把應用做到一個 Todo List 那麼簡單,很多龐大的系統,應用狀態都十分的分散,集中起來用函數去解決實在不能稱為上策。況且,用戶界面中有很多控制項可能會有一些很複雜的狀態,這些控制項的狀態又怎麼去管理呢?除了 OO,我很難想到其他更好的辦法。
Web Components 解決了什麼問題?
Web Components 是 W3C 官方正在實行的標準,具有更廣泛的使用前景,也許將來所有的瀏覽器都可以不使用任何 polyfill 就能享受完整的 Web Components 支持。
所以它到底給我們帶來了什麼?我認為它是前端組件化的最好的體現形式,以自定義標籤為載體,開發者可以將常用的功能或視圖封裝為一個新的標籤,得益於 Shadow DOM 的支持,自定義標籤內外可以做到互不干擾。最重要的是,自定義標籤真正具有自己的屬性、方法,你可以真的像在操作一個對象一樣去操作這個標籤,去控制其狀態,讓它執行相應的操作,而不用像 React 那樣,通過改變狀態去觸發組件的行為變化。熟悉 Native 開發的童鞋也應該知道,Native 的組件其實就是一個個類實例化的對象,它們有屬性,有方法,可以響應事件等等,通過 Web Components,在前端中也可以做到這一點。
舉個簡單的例子,Polymer 的 Paper 元素類別中有一個 paper-listbox 元素,具體效果可以看這個 Demo,它就具有一系列方法,比如你可以對它執行 select 方法,來做到選中列表中的一項,你也可以響應它所發出的一系列事件,非常地符合直覺。
更多的 Polymer 元素可以看這個 Gallery。谷歌官方實現了很多實用的組件,諸如 Ajax、Form、Input Validator 還有一些 Material Design 的控制項,直接拿來用很方便。
Polymer 同時支持雙向綁定,我認為一些輕量級的數據,通過 Polymer 的數據綁定機制就足夠了,自定義標籤不限於 DOM 元素,你也可以只封裝 CSS,或者只封裝邏輯,將 Model 封裝成一個標籤也是完全可以的,然後通過數據綁定,將 Model 標籤的數據和響應的 View 綁定在一起,這樣,我們就可以用 OO 的方式操作 Model 標籤,數據的變化就能立刻反應在 View 上,十分地優雅。
當然了,Polymer 目前也還處於開發過程中,生產環境是否適合我也並不清楚,畢竟不是做前端的,但是業餘拿來研究我認為它還是非常有前景的,我也十分期待 Web Components 正式成為所有瀏覽器的標準後,Web 前端將是一個怎樣的美好景象。
推薦閱讀:
※Webpack構建library時的踩坑經歷
※2017年零基礎轉行前端還能找到工作么?
※你會用CSS實現垂直居中嗎?
※2016 這一年啊~