使用 v-for 指令,將一個數組渲染爲列表項。
v-for 指令須要限定格式爲 item in items 的特殊語法,items是原始數據數組,item是數組中每一個迭代元素的指代別名。數組
<div id="app1"> <li v-for="item in items"> {{ item.message }} </li> </div> ---------- var app1 = new Vue({ el: '#app1', data: { items: [ {message:'Foo'}, {message:'Bar'} ] } })
<div id="app2"> <li v-for="(item,index) in items"> {{parentMessage}} - {{index}} - {{item.message}} </li> </div> ---------- var app2 = new Vue({ el: '#app2', data: { parentMessage: 'Hello!', items: [ {message: 'Foo'}, {message: 'Bar'} ] } })
結果是app
能夠不使用 in而是使用 of 做爲分隔符。
of更加接近 JavaScript 迭代器語法。性能
<div id="app3"> <li v-for="item of items"> {{item.message}} </li> </di ---------- var app3 = new Vue({ el: '#app3', data: { items: [ {message: 'Foo'}, {message: 'Bar'} ] } })
使用 v-for 來遍歷對象的屬性。this
<div id="app4"> <li v-for="value in object"> {{value}} </li> </div> ---------- var app4 = new Vue({ el: '#app4', data: { object:{ firstname: 'Dong', lastname: 'Yu', age: '20' } } })
<div id="app5"> <li v-for="(value,key) in object"> {{key}} : {{value}} </li> </div> ---------- var app5 = new Vue({ el: '#app5', data:{ object:{ no1: 'Dong Yu', no2: 'Dong xixi', no3: 'Dong momo' } } })
結果爲:spa
在遍歷一個對象時,是按照 Object.keys() 得出 key 的枚舉順序來遍歷,沒法保證在全部 JavaScript 引擎實現中徹底一致。prototype
<div id="app6"> <li v-for="(value,key,index) in object"> {{index+1}} - {{key}} - {{value}} </li> </div> ---------- var app6 = new Vue({ el: '#app6', data:{ object:{ firstname: 'Dong', lastname: 'Yu', age: '20' } } })
當 Vue 更新已使用 v-for 渲染的元素列表時,默認會採用「就地填充」策略。
若是數據項的順序發生了變化,不是移動 DOM 元素來匹配列表項的順序,而是Vue 會將每一個元素填充到恰當的位置,最終反映爲,在該特定索引處放置應該呈現的內容。
這個默認模式是高效率的,可是隻適用於當你的列表渲染輸出不依賴於子組件狀態或臨時 DOM 狀態(例如,表單輸入值)時。code
須要從新複用和從新排序現有元素 —— 須要 Vue 跟蹤每一個節點的身份 —— 爲每項提供惟一的 key 屬性對象
理想的 key 值是每項都有惟一的 id。
這是個特殊屬性須要使用 v-bind 將其與動態值綁定在一塊兒。(由於是屬性)blog
<div id="app7"> <li v-for="item in items" :key="item.id"></li> </div>
在使用 v-for 時儘量提供一個 key,除非迭代的 DOM 內容足夠簡單,或者你是故意依賴於默認行爲來得到性能提高。
key 不限於與 v-for 關聯,還能夠其餘場景使用。排序
變化數組方法在調用後會改變原始數組。
Vue將觀察數組的變化數組方法包裹起來,以便在調用這些方法時,也可以觸發視圖更新。這些包裹的方法以下:
能夠打開控制檯,而後對前面示例中的 items 數組調用變化數組方法。
例如:example1.items.push({ message: 'Baz' })。
非變化數組方法 (例如 filter(), concat() 和 slice())不會直接修改操做原始數組而是返回一個新數組。
能夠將舊數組替換爲新數組。
<div id="app8"> <li v-for="item in items"> {{item.message}} </li> <button @click="change()">切換</button> </div> --------- var app8 = new Vue({ el: "#app8", data:{ items:[ {message:"Foo"}, {message:"Bar"} ] }, methods:{ change:function(){ this.items = this.items.filter(function(item){ return item.message.match(/Foo/) }) } } })
Vue並非丟棄現有 DOM 並從新渲染整個列表 。
Vue 實現了一些智能啓發式方法來最大化 DOM 元素重用。
將一個數組替換爲包含重疊對象的另外一個數組是一種很是高效的操做。
因爲 JavaScript 的限制,Vue 沒法檢測到如下數組變更:
var vm = new Vue({ data: { items: ['a', 'b', 'c'] } }) vm.items[1] = 'x' // 不是響應的 vm.items.length = 2 // 不是響應的
解決方法以下:
方法一:
// Vue.set Vue.set(vm.items, indexOfItem, newValue)
方法二:
// Array.prototype.splice vm.items.splice(indexOfItem, 1, newValue)
方法三:
vm.$set(vm.items, indexOfItem, newValue)
vm.items.splice(newLength)
受現代 Javascript 的限制, Vue 沒法檢測到對象屬性的添加或刪除。
var vm = new Vue({ data: { a: 1 } }) // `vm.a` 是響應的 vm.b = 2 // `vm.b` 不是響應的
Vue 不容許在已經建立的實例上動態地添加新的根級響應式屬性。
可使用 Vue.set方法將響應式屬性添加到嵌套的對象上。
還可使用 vm.$set 實例方法,這也是全局 Vue.set 方法的別名。
<div id="app9"> <li v-for="item in items">{{item}}</li> </div> ---------- var app9 = new Vue({ el: '#app9', data: { items: { name: 'Dong Yu' } } }) Vue.set(app9.items,'age',20)
建立一個新的對象,這個對象同時具備兩個對象的全部屬性。
Object.assign(vm.userProfile, { age: 27, favoriteColor: 'Vue Green' }) //添加新的響應式屬性: vm.userProfile = Object.assign({}, vm.userProfile, { age: 27, favoriteColor: 'Vue Green' })
顯示一個數組過濾或排序後的副本,而不是實際改變或重置原始數據,能夠建立一個返回過濾或排序數組的計算屬性。
<div id="app10"> <li v-for="n in evenNumbers"> {{n}} </li> </div> ---------- var app10 = new Vue({ el: '#app10', data:{ number: [1,2,3,4,5,6,7,8,9] }, computed: { evenNumbers:function(){ return this.number.filter(function(num){ return num % 2 === 0 }) } } })
在計算屬性不適用的狀況下(例如,在嵌套的 v-for 循環內),可使用一個 method 方法。
<div id="app11"> <li v-for="n in even(numbers)"> {{n}} </li> </div> ---------- var app11 = new Vue({ el: '#app11', data: { numbers: [1,2,3,4,5,6,7,8,9] }, methods:{ even: function(numbers){ return numbers.filter(function(num){ return num % 2 === 0 }) } } })
<div id="app12"> <li v-for="n in 10"> {{n}} </li> </div>
結果爲 1 2 3 4 5 6 7 8 9 10
渲染多個元素塊
<div id="app13"> <template v-for="item in items"> <li>{{item.msg}}</li> <li>我不是響應式的</li> </template> </div> ---------- var app13 = new Vue({ el: '#app13', data: { items:[ {msg:'啦啦啦'}, {msg:'嘻嘻嘻'} ] } })
結果爲
當它們都處於同一節點時,v-for 的優先級高於 v-if。
v-if 將分別在循環中的每次迭代上運行。
<li v-for="todo in todos" v-if="!todo.isComplete"> {{ todo }} </li>
將 v-if 放置於包裹元素上(或放置於 < template > 上)
<ul v-if="todos.length"> <li v-for="todo in todos"> {{ todo }} </li> </ul> <p v-else>No todos left!</p>