前文回顾
riot.js教程【三】访问DOM元素、使用jquery、mount输入参数、riotjs标签的生命周期;
riot.js教程【二】组件撰写准则、预处理器、标签样式和装配方法;
riot.js教程【一】简介;
共享Mixins
混合开发可以使你很好的复用代码,如下所示:
var OptsMixin = {// the `opts` argument is the option object received by the tag as wellinit: function(opts) {this.on('updated', function() { console.log('Updated!') })},getOpts: function() {return this.opts},setOpts: function(opts, update) {this.opts = optsif (!update) this.update()return this}
}<my-tag><h1>{ opts.title }</h1>this.mixin(OptsMixin)
</my-tag>
在上面这个示例中,你给页面中所有的my-tag标签增加了两个实例方法
getOpts和setOpts
来看下面的示例
var my_tag_instance = riot.mount('my-tag')[0]console.log(my_tag_instance.getOpts()) // will log out any opts that the tag has
另外,init方法是一个特殊的方法,
当一个riot标签加载一个mixin对象时,会执行init方法
init方法不是标签的实例方法,它是不可访问的
上面例子中,我们已经为my-tag设计了一个mixin对象OptsMixin,
那么我们想为这个对象补充一个方法该如何做呢?如下:
function IdMixin() {this.getId = function() {return this._id}
}var id_mixin_instance = new IdMixin()<my-tag><h1>{ opts.title }</h1>this.mixin(OptsMixin, id_mixin_instance)
</my-tag>
所以一个mixin对象可以是一个json对象,
也可以是一个方法的实例
全局的mixins
如果你需要为你所有的标签扩展方法
你就可以使用全局mixins
riot.mixin(mixinObject)
与共享mixins不同,全局mixins会直接被所有的标签加载;
要谨慎使用全局的mixins
HTML内嵌表达式
可以在HTML内部嵌入用大括号包裹的JS表达式,
大括号包裹的JS表达式既可以被用于文本标签,也可以被用于HTML属性
<h3 id={ /* attribute_expression */ }>{ /* nested_expression */ }
</h3>
下面举几个例子:
{ title || 'Untitled' }
{ results ? 'ready' : 'loading' }
{ new Date() }
{ message.length > 140 && 'Message is too long' }
{ Math.round(rating) }
为了使你的HTML标签保持clean
建议原则是尽量使用简洁的JS表达式
如果你的表达式演变的越来越复杂了
那么考虑把表达式里的一些逻辑转义到update事件中去,如下
<my-tag><!-- the `val` is calculated below .. --><p>{ val }</p>// ..on every updatethis.on('update', function() {this.val = some / complex * expression ^ here})
</my-tag>
HTML标签中,拥有布尔值的属性,比如checked, selected这类属性
当表达式的值为false的时候,这些属性是不会添加到HTML标签中的
下面两行代码是等价的
<input checked={ null }><input>
W3C规定,这类属性,就算你没给它设置值,只要他出现在HTML标签内,那么它就等价于给这类属性设置了true的值
再来看下面这行代码
<p class={ foo: true, bar: 0, baz: new Date(), zorro: 'a value' }></p>
这个标签的类名经过计算后是:foo baz zorro
因为bar的值是0,0就是false,只有值是true的才会被应用到标签上
这个特性不一定用于class,还可以用在别的地方
你还可以直接这样写:
<my-tag><p class={ classes }></p><script>hasAnimation() {return true}this.randomNumber = 5this.classes = {foo: true,bar: false,number: '3 > randomNumber',animated: 'hasAnimation()', //注意:这里要写成字符串的形式baz: new Date(),zorro: 'a value'}</script>
</my-tag>
经过计算后P的样式类有foo number animated baz zorro
HTML标签的行内样式也可以写成类似这样
<my-tag><p style={ styles }></p><script>this.styles = {color: 'red',height: '10rem'}</script>
</my-tag>
riotjs会自动把对象转换成描述样式的字符串
<p style="color: red; height: 10rem"></p>
那么如何打印大括号到浏览器呢?可以用下面这种方式:
\\{ this is not evaluated \\}
你如果不喜欢用大括号来告诉riotjs哪行代码是你的表达式
你可以通过配置改变这一点:
riot.settings.brackets = '${ }'
riot.settings.brackets = '\{\{ }}'
注意,标注之间要用一个空格隔开
riotjs的表达式,只能输出(渲染)纯文本的字符串值;
不能输出(渲染)HTML的字符串值
但是,你可以通过变通的方式完成这项工作,如下:
<raw><span></span>this.root.innerHTML = opts.content
</raw><my-tag><p>Here is some raw content: <raw content="{ html }"/> </p>this.html = 'Hello, <strong>world!</strong>'
</my-tag>
注意,这样做很容易受到跨站脚本攻击,千万不要加载不受你控制的数据;