halo,大家好,好久不賤呢!
最近因為看了一些 be 的小說,整個人都比較致鬱::>_
<::>就在昨天,我用了一天的時間寫了 fre,又一個小而美的前端MVMM框架
劃重點:hooks、Proxy、tagged-template、vdom diff
可能你覺得,有了 vue 和 react,沒必要再寫一個了::>_<::>
先看 API:
import { useState, html, render } from 'fre'
function counter() {
const state = useState({
count: 0
})
return html`
${state.count}
`
}
render(html``, document.body)
hooks style 的組件化方案
最先看到的應該是 hooks。
雖然和 react 的 hooks 並不一樣,fre 的 hooks 是通過 Proxy 劫持實現的,react 是通過兩個數組對應實現的。
沒錯,fre 就是因為有了 hooks 才寫的,hooks 使得 function 具有了狀態,其實是另一種組件化方案。
市面上常見的組件化方案:
- react 的方案,class + extend + hoc + render props,依靠 JS
- Xvue 的方案,模板引擎,依靠 vue-loader
- angular 的方案,(我也不知道是啥,沒研究,但是應該可以將 web-components 歸類到這裡)
以上,可以說,各大框架實現組件化的方式各不相同,react 和 vue 都需要 babel,而 web-components 雖然瀏覽器原生支持,但是它自帶的侷限也很多(如 scoped css,直接剝奪了 css 複用的能力)
所以 fre 吸取長處,使用了新的方案:
fre 的方案,function + tagged template +JSX(可選)
沒錯,雖然換了個英文名,但是它就是 ES6 原生支持的 模板字符串 (⊙o⊙)…
tagged template 的模板方案
我一直在尋找能夠運行於瀏覽器的某種寫法,web-components 已經否了,tagged template 是最好的選擇
沒想到,tagged template 不僅僅能夠接近 JSX 的開發體驗,還有很多驚喜:
- html 標準,如 這種簡寫,總之各種的 html5 的寫法都是可以的
- 隔離 js,通過兩個反引號,就再也不用擔心 calss 和 className
當然,它最重要的還是,無需編譯
瀏覽器直接運行會有什麼好處呢?
它可以讓後端語言和jq一樣來使用 fre,卻具備了組件化、響應式數據驅動dom
我曾經說過,大家都在寫前端框架,各種的 react-like、vue-like,迷你化、先進化……
但是無法解決痛點。
前端框架的痛點其實很多,比如SSR
SSR 很多限制,並不是 webpack 配置多麻煩,而是它的限制喪失了很多可能。
首當其衝就是使得除 node 以外的語言僅憑自身的能力無法同構。
所以我寫 fre,從某個角度上,也是為了其他後端語言。
Proxy 和 vdom diff 的數據更新方案
這個議題也被討論很久啦,也就是數據更新的方案,通常也有很多種
- angular ,髒檢查(沒記錯的話是三次循環)
- vue ,對象劫持+vdom diff,vue2 Object.defineproperty
- react,vdom diff
- san,set(xxx,xxx)
我個人,因為就比較專注 vue 和 react,所以也比較推薦對象劫持+vdom diff 的
所以 fre 也是如此,通過 Proxy 實現的劫持,劫持會觸發 rerender,進行 vdom diff
這塊內容,只能說個人喜歡,各種方案都可以,看作者個人吧
這裡順便一提 diff
其實 diff 算法實現蠻多的,大致有兩種:
- react 主導的,兩套 vdom 進行比對,生成 patches,打到真實 dom 上preact 主導的,一套 vdom 直接和 真實dom 比對,直接操作 真實 dom
fre 選擇的是前者,因為 有了 proxy,其實 vdom 可有可無,充其量只是一層抽象而已,那既然抽象它,就應該和 react 一樣抽的徹底點,之後對 diff 的優化,就只是兩個對象的事兒了
https://zhuanlan.zhihu.com/p/52510521
閱讀更多 前端小學生 的文章