Vue2.0 列表渲染(譯)

v-for

我們用v-for 指令根據(jù)一組數(shù)組的選項(xiàng)列表進(jìn)行渲染。v-for 指令需要以 item in items 形式的特殊語法暂吉,items 是源數(shù)據(jù)數(shù)組并且 item 是數(shù)組元素迭代的別名浑度。

基本用法

<ul id="example-1">
    <li v-for="item in items">
      {{ item.message }}
    </li>
</ul>
var example1 = new Vue({
    el: '#example-1',
    data: {
        items: [
            {message: 'foo' },
            {message: 'Bar' }
        ]   
    }
})

v-for 塊內(nèi)部寇窑,我們有完全訪問父作用域的屬性。v-for 還支持一個(gè)可選的第二個(gè)參數(shù)為當(dāng)前項(xiàng)的索引箩张。

<ul id="example-2">
  <li v-for="(item, index) in items">
    {{ parentMessage }} - {{ index }} - {{ item.message }}
  </li>
</ul>
var example2 = new Vue({
  el: '#example-2',
  data: {
    parentMessage: 'Parent',
    items: [
      { message: 'Foo' },
      { message: 'Bar' }
    ]
  }
})

你也可以用 of 替代 in 作為分隔符, 所以它是最接近JavaScript迭代器的語法

<div v-for="item of items"></div>

Template v-for

如同 v-if 模板甩骏,你也可以用帶有 v-for<template> 標(biāo)簽來渲染多個(gè)元素塊。例如:

<ul>
  <template v-for="item in items">
    <li>{{ item.msg }}</li>
    <li class="divider"></li>
  </template>
</ul>

對象迭代 v-for

你也可以用 v-for 通過一個(gè)對象的屬性來迭代先慷。

<ul id="repeat-object" class="demo">
  <li v-for="value in object">
    {{ value }}
  </li>
</ul>
new Vue({
  el: '#repeat-object',
  data: {
    object: {
      FirstName: 'John',
      LastName: 'Doe',
      Age: 30
    }
  }
})

你也可以提供第二個(gè)的參數(shù)為鍵名:

<div v-for="(value, key) in object">
  {{ key }} : {{ value }}
</div>

第三個(gè)參數(shù)為索引:

<div v-for="(value, key, index) in object">
  {{ index }}. {{ key }} : {{ value }}
</div>

<p class="tip">當(dāng)遍歷一個(gè)對象時(shí)横漏,順序是根據(jù) Object.keys() 可枚舉鍵名排列,不保證和JavaScript引擎實(shí)現(xiàn)是一致的熟掂。</p>

整數(shù)迭代 v-for

v-for 也可以取整數(shù)缎浇。在這種情況下,它將重復(fù)多次模板

<div>
  <span v-for="n in 10">{{ n }}</span>
</div>

組件 和 v-for

了解組件相關(guān)知識赴肚,查看 組件 素跺。

在自定義組件里,你可以像任何普通元素一樣用 v-for 誉券。

<my-component v-for="item in items"></my-component>

然而他不能自動傳遞數(shù)據(jù)到組件里指厌,因?yàn)榻M件有自己獨(dú)立的作用域。為了傳遞迭代數(shù)據(jù)到組件里踊跟,我們要用 props

<my-component
  v-for="(item, index) in items"
  v-bind:item="item"
  v-bind:index="index">
</my-component>

不自動注入 item 到組件里是因?yàn)檫@樣能讓組件緊密耦合 v-for 怎么運(yùn)作的踩验。在一些情況下,明確了數(shù)據(jù)的來源讓其組件可重復(fù)使用商玫。

下面是一個(gè)簡單的todo list完整的例子:

<div id="todo-list-example">
  <input
    v-model="newTodoText"
    v-on:keyup.enter="addNewTodo"
    placeholder="Add a todo"
  >
  <ul>
    <li
      is="todo-item"
      v-for="(todo, index) in todos"
      v-bind:title="todo"
      v-on:remove="todos.splice(index, 1)"
    ></li>
  </ul>
</div>
Vue.component('todo-item', {
  template: '\
    <li>\
      {{ title }}\
      <button v-on:click="$emit(\'remove\')">X</button>\
    <\li>\
  ',
  props: ['title']
})

new Vue({
  el: '#todo-list-example',
  data: {
    newTodoText: '',
    todos: [
      'Do the dishes',
      'Take out the trash',
      'Mow the lawn'
    ]
  },
  methods: {
    addNewTodo: function () {
      this.todos.push(this.newTodoText)
      this.newTodoText = ''
    }
  }
})

key

當(dāng)Vue.js用 v-for 正在更新已渲染過的元素列表時(shí)箕憾,它默認(rèn)用 “就地復(fù)用” 策略。如果數(shù)據(jù)項(xiàng)的順序被改變拳昌,而不是移動DOM元素來匹配列表的順序袭异,Vue將簡單復(fù)用此處每個(gè)元素,并且確保它在特定索引下顯示已被渲染過的每個(gè)元素炬藤。這個(gè)類似Vue 1.X的 track-by="$index" 御铃。

這個(gè)默認(rèn)的模式是有效的碴里,但是只適合你的列表渲染輸出時(shí)不依賴子組件狀態(tài)或臨時(shí)DOM狀態(tài)(例如:表單輸入框的值)

給Vue一個(gè)提示以便它能跟蹤每個(gè)節(jié)點(diǎn)身份,并且因此重新使用和重新排序現(xiàn)有元素上真,你需要為每項(xiàng)提供一個(gè)唯一 key 屬性咬腋。一個(gè)有效的 key 值是每項(xiàng)唯一ID. 這個(gè)特殊的屬性相當(dāng)于Vue 1.x的 track-by ,但它像一個(gè)變量睡互,所以你需要用 v-bind 來綁定動態(tài)值(簡潔寫法如下)

<div v-for="item in items" :key="item.id">
  <!-- content -->
</div>

它建議盡可能用 v-for 時(shí)提供一個(gè) key 帝火。除非迭代DOM內(nèi)容很簡單,或者你有意要依賴于對性能提升的默認(rèn)行為湃缎。

因?yàn)樗荲ue識別節(jié)點(diǎn)的通用的機(jī)制犀填,key 還具有并不特別依賴于 v-for 的其他用途,我們將在后面的指南中看到其他用途嗓违。

數(shù)組更新檢測

突變方法

Vue包含一組觀察數(shù)組的改變原數(shù)組的方法九巡,所以它們也將會觸發(fā)視圖更新。這些方法如下:

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

你打開控制臺蹂季,然后用前面例子的 items 數(shù)組調(diào)用突變方法:example1.items.push({ measage: 'Baz' })

重塑數(shù)組

突變方法冕广,顧名思義,改變原始數(shù)組的稱呼偿洁。相比之下撒汉,也有不改變原組數(shù)的方法,例如:filter() 涕滋,concat() 睬辐,slice() 。這些不會改變原始數(shù)組宾肺,但總是返回一個(gè)新的數(shù)組溯饵。當(dāng)用不改變原數(shù)組的方法時(shí),你只需替換舊數(shù)組用新的:

example1.items = example1.items.filter(function (item) {
  return item.message.match(/Foo/)
})

你可你能認(rèn)為這將導(dǎo)致Vue丟掉現(xiàn)有DOM和重新渲染整個(gè)列表锨用。幸運(yùn)的是丰刊,事實(shí)并非如此。Vue實(shí)現(xiàn)了一些智能化去最大化的重用DOM元素增拥,所以用另外含有重疊對象的數(shù)組替換數(shù)組是非常高效的操作啄巧。

注意事項(xiàng)

由于JavaScript的限制,Vue不能檢測以下變動的數(shù)組:

  1. 當(dāng)你直接設(shè)置一個(gè)項(xiàng)的索引時(shí), 例如: vm.items[indexOfItem] = newValue
  2. 當(dāng)你修改數(shù)組的長度時(shí), 例如: vm.items.length = newLength

為了避免第一種情況, 以下兩種方式將達(dá)到像 vm.items[indexOfItem] = newValue 的效果掌栅, 同時(shí)也將觸發(fā)狀態(tài)更新:

// Vue.set
Vue.set(example1.items, indexOfItem, newValue)
// Array.prototype.splice`
example1.items.splice(indexOfItem, 1, newValue)

避免第二種情況, 使用 splice:

example1.items.splice(newLength)

顯示過濾/排序結(jié)果

有時(shí)我們無需實(shí)際改變或重置原始數(shù)據(jù)對數(shù)組進(jìn)行過濾或排序秩仆。在這種情況下,你可以創(chuàng)建計(jì)算的屬性返回過濾或排序的數(shù)組渣玲。

例如:

<li v-for="n in evenNumbers">{{ n }}</li>
data: {
  numbers: [ 1, 2, 3, 4, 5 ]
},
computed: {
  evenNumbers: function () {
    return this.numbers.filter(function (number) {
      return number % 2 === 0
    })
  }
}

此外, 你也可以只使用一種方法計(jì)算 (例如: 嵌套在 v-for 里循環(huán))逗概,但是性能是低效的:

<li v-for="n in even(numbers)">{{ n }}</li>
data: {
  numbers: [ 1, 2, 3, 4, 5 ]
},
methods: {
  even: function (numbers) {
    return numbers.filter(function (number) {
      return number % 2 === 0
    })
  }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市忘衍,隨后出現(xiàn)的幾起案子逾苫,更是在濱河造成了極大的恐慌,老刑警劉巖枚钓,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件铅搓,死亡現(xiàn)場離奇詭異,居然都是意外死亡搀捷,警方通過查閱死者的電腦和手機(jī)星掰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來嫩舟,“玉大人氢烘,你說我怎么就攤上這事〖已幔” “怎么了播玖?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長饭于。 經(jīng)常有香客問我蜀踏,道長,這世上最難降的妖魔是什么掰吕? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任果覆,我火速辦了婚禮,結(jié)果婚禮上殖熟,老公的妹妹穿的比我還像新娘局待。我一直安慰自己,他們只是感情好菱属,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布燎猛。 她就那樣靜靜地躺著,像睡著了一般照皆。 火紅的嫁衣襯著肌膚如雪重绷。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天膜毁,我揣著相機(jī)與錄音昭卓,去河邊找鬼。 笑死瘟滨,一個(gè)胖子當(dāng)著我的面吹牛候醒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播杂瘸,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼倒淫,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了败玉?” 一聲冷哼從身側(cè)響起敌土,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤镜硕,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后返干,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體兴枯,經(jīng)...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年矩欠,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了财剖。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,688評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡癌淮,死狀恐怖躺坟,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情乳蓄,我是刑警寧澤咪橙,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站栓袖,受9級特大地震影響匣摘,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜裹刮,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一音榜、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧捧弃,春花似錦赠叼、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至买鸽,卻和暖如春涧郊,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背眼五。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工妆艘, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人看幼。 一個(gè)月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓批旺,卻偏偏與公主長得像,于是被迫代替她去往敵國和親诵姜。 傳聞我的和親對象是個(gè)殘疾皇子汽煮,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,573評論 2 353

推薦閱讀更多精彩內(nèi)容