riot.js教程【六】循環、HTML元素標籤

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

循環

能夠經過each屬性來達到標籤循環,以下:jquery

<todo>
  <ul>
    <li each={ items } class={ completed: done }>
      <input type="checkbox" checked={ done }> { title }
    </li>
  </ul>

  this.items = [
    { title: 'First item', done: true },
    { title: 'Second item' },
    { title: 'Third item' }
  ]
</todo>

在上面的代碼中,具備each屬性的元素,會被重複N次,N等於items數組的元素數量;數組

當你經過push,slice,splice改變數組數量的時候,DOM元素也會隨之變化app

上下文

全部被循環的元素,都擁有本身的上下文,請看以下代碼:dom

<todo>
  <div each={ items }>
    <h3>{ title }</h3>
    <a onclick={ parent.remove }>Remove</a>
  </div>

  this.items = [ { title: 'First' }, { title: 'Second' } ]

  remove(event) {

    // looped item
    var item = event.item

    // index on the collection
    var index = this.items.indexOf(item)

    // remove from collection
    this.items.splice(index, 1)
  }
</todo>

在被循環的元素內部,想訪問數組子對象的屬性,能夠直接訪問,如:{title}oop

若是想訪問父元素的屬性,就須要加上parent,好比:{ parent.remove },由於上下文不一致了性能

在 parent.remove方法中,可使用event.item對象訪問當前數組元素的屬性,this

parent.remove方法執行完以後,會執行父組件的update事件;code

當在一個父組件實例執行this.update()的時候 ,該父組件下的全部子組件都會更新,htm

自定義的循環標籤

一個自定義的標籤也能夠被標記爲循環標籤,以下:

<todo-item each="{ items }" data="{ this }"></todo-item>

你能夠經過data="{ this }"把當前標籤的實例傳遞給todo-item的實例

簡單數組循環

循環的數組元素不必定是對象,以下:

<my-tag>
  <p each="{ name, i in arr }">{ i }: { name }</p>

  this.arr = [ true, 110, Math.random(), 'fourth']
</my-tag>

對象屬性循環

與簡單數組循環相對,下面的代碼是對象屬性循環

<my-tag>
  <p each="{ value, name  in obj }">{ name } = { value }</p>

  this.obj = {
    key1: 'value1',
    key2: 1110.8900,
    key3: Math.random()
  }
</my-tag>

注意,對象屬性循環有性能問題,不推薦使用;

riotjs是經過JSON.stringify來判斷對象是否有變動,以此來決定是否要更新HTML元素

key屬性

你能夠在循環標籤的時候,使用key屬性

<loop>
  <ul>
    <li each={ user in users } key="id">{ user.name }</li>
  </ul>
  <script>
    this.users = [
      { name: 'Gian', id: 0 },
      { name: 'Dan', id: 1 },
      { name: 'Teo', id: 2 }
    ]
  </script>
</loop>

你甚至能夠給key屬性賦值爲方法

<loop>
  <ul>
    <li each={ user in users } key={ user.id() }>{ user.name }</li>
  </ul>
  <script>
    this.users = [
      { name: 'Gian', id() { return 0 } },
      { name: 'Dan', id() { return 1 } },
      { name: 'Teo', id() { return 2 } }
    ]
  </script>
</loop>

虛擬標籤

有的時候,你須要循環多個標籤,可是你又不想在這多個標籤上面套一個wrapper,

這個時候你就能夠用虛擬標籤,代碼以下:

<dl>
  <virtual each={item in items}>
    <dt>{item.key}</dt>
    <dd>{item.value}</dd>
  </virtual>
</dl>

你能夠在虛擬標籤上添加if 或者 data-is屬性

<virtual data-is="my-tag" if={condition}>
  <p>Show me with no wrapper on condition</p>
</virtual>

HTML元素標籤

你能夠把HTML元素看成riot標籤使用,但只能在body內這麼用,以下:

<ul data-is="my-list"></ul>

riot.mount('my-list')

當你碰到這種狀況的時候,你須要使用data-is屬性

<my-fancy-options>
  <option>foo</option>
  <option>bar</option>
</my-fancy-options>

<!-- 下面的代碼是錯誤的, 一個 select 標籤 只容許出現<option> 子元素 -->
<select>
  <my-fancy-options />
</select>

<!-- 下面的代碼是正確的 由於渲染 <option> 標籤時會使用 <select> 做爲父標籤 -->
<select data-is='my-fancy-options'></select>

本系列寫完了,祝好!

相關文章
相關標籤/搜索