1. v-for循环遍历数组
(1)v-for
指令需要使用 item in items
形式的特殊语法
-
{{ item.message }}
注意写法:
v-for是在li标签上(li标签是要展示数据的标签)
数组items在data中,items是数组,每项是对象
使用数据的时候是mustache语法
(2)在 v-for
块中,我们拥有对父作用域属性的完全访问权限。v-for
还支持一个可选的第二个参数为当前项的索引。
-
{{ parentMessage }} - {{ index }} - {{ item.message }}
结果:
注意:父级作用域就是data中的其他数据,index是当前索引值,是一个可选的参数,item、items和index都是自定义的,注意他们是如何申明的。
注意:两个参数时,写在()中
注意:可用of代替in
2. v-for循环遍历对象
-
{{ value }}
注意:遍历的对象直接写在data中;new Vue没有赋值给变量
(2)第二个的参数为键名
-
{{key}} : {{ value }}
结果:
(3)第三个参数为索引
{{ index }}. {{ key }}: {{ value }}
注意:在遍历对象时,是按 Object.keys()
的结果遍历,但是不能保证它的结果在不同的 JavaScript 引擎下是一致的。
问:Object.keys()是什么,哪些js引擎不支持???
Object.keys
返回一个所有元素为字符串的数组,其元素来自于从给定的object
上面可直接枚举的属性。这些属性的顺序与手动遍历该对象属性时的一致。
举例:
// simple array
var arr = ['a', 'b', 'c'];
console.log(Object.keys(arr)); // console: ['0', '1', '2']
// array like object
var obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.keys(obj)); // console: ['0', '1', '2']
// array like object with random key ordering
var anObj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.keys(anObj)); // console: ['2', '7', '100']
// getFoo is a property which isn't enumerable
var myObj = Object.create({}, {
getFoo: {
value: function () { return this.foo; }
}
});
myObj.foo = 1;
console.log(Object.keys(myObj)); // console: ['foo']
当是对象的时候,若属性名(key值)是数字时,系统会根据对象内的属性名的数值自动进行排序,调用该Object.keys(obj)方法时,得到的得到由key值组成的数组是按顺序排列的
系统会根据对象的属性进行排序:
执行Object.keys(obj)时:
3. key
当 Vue.js 用 v-for
正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。这个默认的模式是高效的,但是只适用于不依赖子组件状态或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出。
为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key
属性。理想的 key
值是每项都有的唯一 id。你需要用 v-bind
来绑定动态值 (在这里使用简写):
建议尽可能在使用 v-for
时提供 key
,除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升。
因为它是 Vue 识别节点的一个通用机制,key
并不与 v-for
特别关联,key 还具有其他用途,我们将在后面的指南中看到其他用途。
4. 数组
(1)变异方法(mutation method)变异方法对数据的操作是响应式的
Vue 包含一组观察数组的变异方法,方法如下:
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
你打开控制台,然后用前面例子的 items
数组调用变异方法:example1.items.push({ message: 'Baz' })
(2)非变异方法(non-mutation method)非变异方法对数据的操作不是响应式的,但可以通过改变数组地址的方式,响应式改变数据。比如:filter()
, concat()
和 slice()
。这些不会改变原始数组,但总是返回一个新数组。
当使用非变异方法时,可以用新数组替换旧数组:
example1.items = example1.items.filter(function (item) {
return item.message.match(/Foo/)
})
变异方法是数组的索引地址发生了改变,在新的索引地址里,有新的数据。通过这个原理,我们可以直接用vm.items= 新数组来改变数组的索引,使得页面响应式变化。
注意:由于 JavaScript 的限制,Vue 不能检测以下变动的数组:
vm.items[indexOfItem] = newValue(数组内的部分内容发生改变时,索引地址没有改变,而如果数组索引地址发生改变,页面内容就会响应式发生变化)
vm.items.length = newLength
下面例子中对数组的改变不是响应式的:(数据其实发生了变化,但是页面没有响应式的渲染)
var vm = new Vue({
data: {
items: ['a', 'b', 'c']
}
})
vm.items[1] = 'x' // 不是响应性的
vm.items.length = 2 // 不是响应性的
(1)为了解决vm.items[indexOfItem] = newValue
不是响应式的,下面有两种方法:
方法一:Vue.set(vm.items, indexOfItem, newValue) // Vue.set
方法二:vm.items.splice(indexOfItem, 1, newValue) // Array.prototype.splice
也可以使用 vm.$set
实例方法,该方法是全局方法 Vue.set
的一个别名:
vm.$set(vm.items, indexOfItem, newValue)
(2)了解决vm.items.length = newLength
,可以使用 splice
:
vm.items.splice(newLength)
补充:对多个标签进行循环,需要用template标签(该标签的作用是不在浏览器中渲染)
{{item.id}}
{{item.name}}————{{item.age}}
注意::key不能放在template标签上;也不能在template的子标签中都放入key,只在一个标签中放入key即可。
理由???对key的理解
5. 对象
还是由于 JavaScript 的限制,Vue 不能检测对象属性的添加或删除
下面例子中,vm.b = 2 不是响应式的添加
var vm = new Vue({
data: {
a: 1
}
})
// `vm.a` 现在是响应式的
vm.b = 2
// `vm.b` 不是响应式的
注意:对于已经创建的实例,Vue 不能动态添加根级别的响应式属性(什么是根级别?)
但是,可以使用 Vue.set(object, key, value)
方法向嵌套对象添加响应式属性
比如:添加一个新的 age
属性到嵌套的 userProfile
对象
-
{{key}} : {{ value }}
结果:
当在控制台中输入代码:Vue.set(vm.userProfile, 'age', 27)
结果:响应式的生成了一条新的数据
当然也可以用vm.$set,set的实例方法
(2)给对象赋值多个属性
使用 Object.assign()
或 _.extend(),
用两个对象的属性创建一个新的对象
vm.userProfile = Object.assign({}, vm.userProfile, {
age: 27,
favoriteColor: 'Vue Green'
})
注意:空对象{}, 对象vm.userProfile,新属性组成的对象
(3)可以修改对象的引用地址,userProfile执行一个新的地址,即新的对象{}
但是要注意:对对象属性值的修改,可以直接操作,vm.userProfile.name = 'zhu',这是响应式的
6. filter
过滤数据数据,而不是改变数组
- {{ n }}
结构分析:计算属性computed中定义一个函数,该函数返回结果是:由数组numbers操作得到的新的数组;li标签中用v-for指令,用item in items语法,对数组进行循环遍历。
如果计算属性不适合,可以用一个方法:
- {{ n }}
结构解析:methods对象中,定义一个even方法,该方法需要传入参数numbers,将数组numbers的操作得到的新数组返回给函数even,要注意在li标签中v-for循环遍历时,items的写法,even(numbers)
7. v-for中的items可以是整数
- {{ n }}
结果:
8. v-for在组件中的使用
新版版中,在组件中使用v-for时,必须使用key
注意:数据不会自动传到组件中,因为组件有自己独立的作用域,这样也可以让同一组件在其他场合多次使用(复用性)。
手动传值到组件中:
demo:
结果:
对该demo解析:label标签中的for是与input的id对应的;注意is="todo-item"
属性,在使用 DOM 模板时十分必要的,因为在
元素内只有 元素会被看作有效内容,这样做实现的效果与
相同,但是可以避开一些潜在的浏览器解析错误;li标签中的v-for是循环遍历;v-bind:key,key必须结合v-for使用,值是item.id;v-bind:title类似于key(也必须存在吗?);v-on:remove也是一个指令,移除指令
Vue.compenont中的todo-itme是组件的名字,使用的时候是用名字标签
9. v-for和v-if处于同一节点,v-for
的优先级比 v-if
更高,这意味着 v-if
将分别重复运行于每个 v-for
循环中,跳过某次循环或者不跳过某次循环
{{ todo }}
而如果你的目的是有条件地跳过循环的执行,那么可以将 v-if
置于外层元素 (或 )上。跳过整个循环或者不跳过整个循环。如
-
{{ todo }}
No todos left!