注:本文基于Riot.js v2.5.0版本
Mixin 可以将公共代码在不同标签之间方便地共享,可以混入 Object 和 new function(){}。
var OptsMixin = {
init: function() {
this.on('updated', function() { console.log('Updated!') })
},
getOpts: function() {
return this.opts
},
setOpts: function(opts, update) {
this.opts = opts
if(!update) {
this.update()
}
return this
}
}
<my-tag>
<h1>{ opts.title }</h1>
this.mixin(OptsMixin)
</my-tag>
声明式 mixin 可在文件之间和项目之间共享 mixin:
riot.mixin("defaultData", {
author: "ddfe",
email: "shield@didichuxing.com"
});
// in custom tag
this.mixin("defaultData");
e.preventUpdate = true
来禁止这种行为。this.update()
方法被调用时this.update()
被调用时. 更新从父亲到儿子单向传播。riot.update()
方法被调用时, 会更新页面上所有的表达式。
100%纯 JavaScript:
{ title || 'Untitled' }
{ results ? 'ready' : 'loading' }
{ new Date() }
{ message.length > 140 && 'Message is too long' }
{ Math.round(rating) }
可放在 html 节点中,也可作为文本节点嵌入:
<h3 id={ /* 属性表达式 */ }>
{ /* 嵌入表达式 */ }
</h3>
注:可通过riot.settings.brackets
自定义花括号
riot.mount
方法的参数设置,而子标签的选项通过标签属性来传递。
<script> riot.mount('account', { plan: { name: 'ddfe', age: '4' } }) </script>
name
或 id
属性的 DOM 元素将自动被绑定到上下文中,可直接访问
if = {expression}
show
hide
each = {items}
(对象数组)or each = {name, i in items}
(非对象数组) or each = {name,value in items}
(对象)(不建议使用)
循环中的每一项将建立一个新的上下文,子标签通过 parent 访问父标签定义的方法和属性。
自定义标签会被编译为 JavaScript
Riot 提供 Observable 以便组件间通信,实现模块化。
// 方法1,创建一个观察者,返回一个实例,之后该对象便可以触发和监听事件
var ddfe = riot.observable({
});
//方法2,使 ddfe 成为观察者
riot.observable(ddfe);
// 监听事件
ddfe.on("event1", function(data1, data2){
// 监听event1事件
// data1 和 data2 是trigger传入的参数
// data1 = 1, data2 = 2
console.log(data1, data2);
});
// 发布一个事件
// 该事件带有 1 和 2 作为参数
// 上面的on("event1")的回调fn将会执行
ddfe.trigger("event1", 1, 2);
// 解除 event1 的所有监听,第二个参数可选
// 如果有第二个参数 [function],则只解绑该函数
ddfe.off("event1");
// one 与 on 类似,只是 one 如果执行过一次,就自动解除绑定
ddfe.one("event1", function(data1){
console.log(data1);
});
ddfe.trigger("event1", 1, 2);
//删除所有事件的所有监听器
ddfe.off('*')
//对所有的事件删除指定的回调函数
ddfe.off('*',fn)
一个最小化的路由器实现
功能:
API:
riot.route(callback)
riot.route(function(collection, id, action) { }) //如果 url 变为 customers/987987/edit,则 //collection = 'customers' //id = '987987' //action = 'edit'
riot.route(filter, callback)
// 精确匹配 `/fruit` riot.route('/fruit', function(name) { console.log('The list of fruits') }) // 如果 url 变成 `/blog/2015-09/01`, // 回调的参数将被捕捉成 '2015', '09' 和 '01' riot.route('/blog/*-*/*', function(year, month, date) { console.log('The page of ' + year + '-' + month + '-' date) })
riot.route.create()
返回一个新的路由上下文
<first-tag> <p>First tag</p> <script> var subRoute = riot.route.create() // 创建新的路由上下文 subRoute('/fruit/*', function(name) { /* 公用的部分 */ }) </script> </first-tag> <second-tag> <p>Second tag</p> <script> var subRoute = riot.route.create() // 创建新的路由上下文 subRoute('/fruit/apple', function(name) { /* 个别的部分 */ }) </script> </second-tag>
riot.route(to[, title, shouldReplace])
在内部实现中,
shouldReplace
, 将使用 history.pushState()
.shouldReplace
, 将使用history.replaceState()
.riot.route.start()
开始监听路由变化,需要手动调用
riot.route.start(autoExec)
riot.route.start(true) <=> riot.route.start()+riot.route.exec()
riot.route.stop()
riot.route.query()
// 如果 url 变成 `/search?keyword=Apple&limit=30` 将会匹配 riot.route('/search..', function() { var q = riot.route.query() console.log('Search keyword: ' + q.keyword) console.log('Search limit: ' + q.limit) })
riot.route.base(base)
修改基础路径
riot.route.parser(parser[, secondParser])
riot.route('/fruit/apple', function() { /* */ }) // 路由-B (1)
riot.route('/fruit/orange', function() { /* */ }) // 路由-C (2)
riot.route('/fruit/*', function(name) { /* */ }) // 路由-A (3)
riot.route(function() { /* */ }) // 路由-X (3)
riot.route('/fruit/*', function() { /* */ }) // 路由-Y (1)
riot.route('/sweet/*', function() { /* */ }) // 路由-Z (2)