使用 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>