riot.js教程【四】Mixins、HTML內嵌表達式

前文回顧
riot.js教程【三】訪問DOM元素、使用jquery、mount輸入參數、riotjs標籤的生命週期;
riot.js教程【二】組件撰寫準則、預處理器、標籤樣式和裝配方法;
riot.js教程【一】簡介;html

共享Mixins

混合開發可使你很好的複用代碼,以下所示:jquery

var OptsMixin = {
  // the `opts` argument is the option object received by the tag as well
  init: function(opts) {
    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>

在上面這個示例中,你給頁面中全部的my-tag標籤增長了兩個實例方法express

getOpts和setOptsjson

來看下面的示例瀏覽器

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方法是一個特殊的方法,dom

當一個riot標籤加載一個mixin對象時,會執行init方法this

init方法不是標籤的實例方法,它是不可訪問的lua

上面例子中,咱們已經爲my-tag設計了一個mixin對象OptsMixin,spa

那麼咱們想爲這個對象補充一個方法該如何作呢?以下:設計

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 update
  this.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 = 5

    this.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>

注意,這樣作很容易受到跨站腳本攻擊,千萬不要加載不受你控制的數據;

相關文章
相關標籤/搜索