Riot.js 中文文檔
本系列文章將有選擇地翻譯Riot.js 2.X 的英文文檔,同時加入一點筆者自己的評價和使用心得。第一篇著重介紹Riot的基本特點
Riot.js 特點概述
-
??自定義標簽??
</ul>
Riot.js 支持在IE8+中自定義標簽,并且這些標簽是人類可讀的
//demo 1 <todo> <!-- layout --> <h3>{ opts.title }</h3> <ul> <li each={ item, i in items }>{ item }</li> </ul> <form onsubmit={ add }> <input> <button>Add #{ items.length + 1 }</button> </form> <!-- logic --> <script> this.items = [] add(e) { var input = e.target[0] this.items.push(input.value) input.value = '' } </script> </todo>
標簽的命名由你決定
<body> <h1>Acme community</h1> <forum-header/> <forum-content> <forum-threads/> <forum-sidebar/> </forum-content> <forum-footer/> <script>riot.mount('*', { api: forum_api })</script></body>
這語法就像React+Polymer,嗯,不過學習曲線非常小。標簽的屬性可以用一種很干凈的方法加進去。
-
Virtual DOM
虛擬DOM是React這類框架提供的重要特性之一,Riot.js也提供了這個特性的一部分功能
-
和React一樣,任何DOM操作都將進行比對后插入真實的DOM,保證DOM操作數量最小化
-
單向響應的數據流,只能從父節點向子節點傳遞
-
大部分表達式都可以通過(服務器)預編譯并緩存來提高性能
-
生命周期事件,可以控制整個流程
-
貼近標準
??Riot.js有一些和其他框架不同的地方??
-
??沒有單獨定義一套事件系統
-
完美支持IE8
-
渲染過的DOM可以被其他庫100%控制
-
沒有定義HTML根元素(筆者注,這里應該是指Angular的ngBody),也沒有使用data-屬性
-
懶人專用語法
Riot.js的一個設計目標是用盡可能小的語法改動來實現強大的功能
-
很快捷的基本語法:class={ enabled: is_enabled, hidden: hasErrors() }
-
沒有React那額外的render、state、construtor什么什么的
-
要插入一個屬性?Add #{ items.length + 1 } or class="item { selected: flag }"
-
在預編譯之前用<script>標簽來包裹JS代碼,可有可無(筆者注,只能在額外的需要預編譯的.tag文件中這么用)
-
可以用ES6、TypeScript、CoffeeScript或者其他你喜歡的JS擴展語言
-
體積小但功能全
Riot.js比起React、Ploymer什么的體積小的多的多(壓縮后不超過5K),但提供了大部分常用的功能
像事件庫、路由之類的,用來創建 Reactive 的用戶界面
-
細節特性
-
Riot.js不像React,是基于DOM而不是基于字符串的,初始化組件時,Riot會遍歷一課DOM樹,然后從樹中提出表達式并放進一個數組,每個表達式都有一個指向DOM節點的“指針”,每次運行這些表達式其實是先計算這些表達式再和DOM比較,當某個值改變的時候那個DOM節點也會改變。也可以認為Riot有一個“虛擬DOM”,只是簡單的多(筆者注,由于Riot沒有組件機制,整個頁面就是一個“組件”,如果頁面DOM結構很大的話,性能會很差,因為它會遍歷整個DOM,和Angular初始化時一樣)。由于這些表達式很快速,并且能被緩存更新周期,所以做100或者1000個表達式幾乎只要1ms。因為HTML布局在每次更新后會隨機修改,所以React的同步算法是很復雜的,這是個很大的挑戰,FB的工程師能搞定真的很厲害!我們認為可以進一步避免復雜的比較,Riot里面HTML結構是定死的,只有“loop”和條件能增加或者刪除元素,比如,一個<div>是不能被轉換成<label>的,Riot只會更新那些沒有復雜的子樹替換的表達式。
-
React只處理UI,專注一個點是很正確的決策。FB推薦開發者用Flux去結構化客戶端代碼,這是一種比框架的龐大的模式,讓人腦洞大開。Riot只捆綁了一個自定義標簽、一個事件觸發器(叫Oservable)還有一個Router,我們相信這是客戶端APP的基本模塊,事件負責模塊化,Router負責URL還有后退按鈕(筆者注,Riot可沒集成Pjax。。),自定義標簽負責UI。就像Flux,Riot就是這么個靈活的、給開發者更多架構決策空間。親們可以用Router和Oservable來做一個類似于Flux的架構
-
和Polymer比較起來,在概念上差不多,細節的差別還是很大滴。Riot只更新不得不被更新的、需要改動HTML展示數據的DOM節點;Polymer的語法更復雜;P導入獨立組件時是這樣的:link rel="import",P必須用XHRs去排列他們,這樣很慢也很痛苦,Riot用script src 來導入,你可擴展Riot,把你常用的幾個標簽組合起來封裝成新工具;P是用雙向數據綁定的;P沒法在服務器預編譯。
-
最后扯一句,Riot比上面兩個的體積小22倍
筆者注
從官網介紹來看Riot是很強大的,不過親們要知道的是體積越少說明功能越簡單,很多細節需要自己去增加,下面筆者列出一些相比React缺失的特性以及列出筆者認為合適的使用場景
-
Riot.js沒有React最重要的“組件化”特性,甚至不是完整的MVP(整個就是一個M一個V一個P,沒有分離代碼的機制),自然也沒有Props這類東西,所謂“單向數據流”,需要你自己擴展;另外,Riot中只能用Loop和Conditions來改動HTML
-
Riot.js 2.X開始不再注重“MVP”,這個特性幾乎體現不出來了,Riot的模塊化更多只是用不同“事件”來區分
-
Riot.js 的性能嘛。。在一個稍大的APP上其實勢必React差一點的。。畢竟兩個“虛擬DOM”是不同的實現
-
Riot.js很多“特性”都只是個規范(比如Router),并沒有實現和封裝,這需要你自己來,當然,插件機制還沒有做好呢,目前說的“靈活”更多來自于Undefined,而非選擇的多樣化
所以可能的使用場景是:
-
一個簡單的WebApp,沒有太多的JS代碼,也不是很關注“組件化”
-
簡單的手機App,或者“無后臺”的客戶端WebApp(即服務器只傳一堆數據,而渲染界面之類的工作全部交給客戶端)
嗯,筆者一直在強調“小型”,因為除非你自己擴展Riot,否則這只能用在單人團隊上。
當然Riot也有很多優秀的特性,官網的介紹里可沒說
-
Riot.js 的“loop”特性非常適合新聞類APP等需要展示大量遍歷和渲染List的場景
-
Riot.js 提供了類似JSX的JSHTMLCSS混寫特性,只是JSX是把HTML寫在JS里,而Riot.js是把JS插到HTML里。不用擔心JS和HTML會黏起來,Riot.js提供了一套很簡單的模板引擎用于分離JS和HTML