Riot.js 中文文档

jopen 9年前

本系列文章将有选择地翻译Riot.js 2.X 的英文文档,同时加入一点笔者自己的评价和使用心得。第一篇着重介绍Riot的基本特点

Riot.js 特点概述

  • 自定义标签

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


中文文档(2)传送门