如果阅读有疑问的话,欢迎评论或私信!!
文章目录
- 列表渲染
- v-for
- v-for 与对象
- 在 `v-for` 里使用范围值
- `template` 上的 `v-for`
- v-for与v-if
- 通过key管理状态
- 组件上使用v-for
- 数组变化侦测
列表渲染
v-for
在我们想要渲染出一个数组中的元素时,在JavaScript中,我们可能会想到循环使用document.createElement
创建标签,并且赋予变量值。
而vue中提供给了我们v-for
指令,可以更方便快捷的渲染一个列表标签。v-for
中的值需要使用item in items
的语法,其中item是别名
,也就是自命名的变量
,用于在当前作用域中使用。而items是一个数组名。例如:
<template><p v-for="myCustom in myArr" class="active">{{ myCustom }}</p>
</template><script>
export default {data() {var myArr = [1,2,3,4,5,6,7,8,9,10]return {myArr};}
};
</script>
该代码渲染除了10个p标签,并且同时class等属性也会保存。
除此之外,我们可以使用v-for指令的第二个可选参数来使用数组中的索引值。例如:
<template><p v-for="(myCustom,index) in myArr" class="active">{{ myCustom }} - {{ index }}</p>
</template><script>
export default {data() {var myArr = [1,2,3,4,5,6,7,8,9,10]return {myArr};}
};
</script>
在官方文档中有一句话:在 v-for
块中可以完整地访问父作用域内的属性和变量。也就是我们可以访问myArr的同胞属性,emm…这个应该本来是可以的吧,只要是这个实例中data返回的对象,都可以被插入到DOM中。这句话也可能是为了给下文嵌套v-for
讲的。
在多层嵌套的v-for中,作用域的方式和多层嵌套for循环的方式比较像,父作用域无法访问子作用域,而子作用域可以方法父作用域。例如:
<li v-for="item in items"><span v-for="childItem in item.children">{{ item.message }} {{ childItem }}</span>
</li>
在vue文档中,提到可以使用of
分隔符替代in
,这个用法的意图可能是为了根据用户不同风格提供的,在JavaScript中,for-of
用来遍历一个对象,来表示每个对象值,而for-in
会返回索引值。具体怎么使用都可以,自己怎么喜欢怎么来。例如:
<div v-for="myCustom of myArr"></div>
v-for 与对象
v-for
指令对数组和对象的使用方法类似,只是对于对象,第二个参数
为对象的键
,第三个参数
才是目前迭代的位置索引
。关于v-for对对象键的遍历,来源于ES6中Object原型上的keys方法
所得到的数组。
例如:
<template><p v-for="(myCustom,currentKey,currentIndex) in author" class="active">{{ myCustom }} - {{ currentKey }} - {{ currentIndex }}</p>
</template><script>
export default {data() {var author = {name: "John Doe",books: ["Vue 2 - Advanced Guide","Vue 3 - Basic Guide","Vue 4 - The Mystery",],};return {author};}
};
</script>
输出效果:
John Doe - name - 0
[ “Vue 2 - Advanced Guide”, “Vue 3 - Basic Guide”, “Vue 4 - The Mystery” ] - books - 1
在 v-for
里使用范围值
v-for
可以直接接受一个整数值。在这种用例中,会将该模板基于 1...n
的取值范围重复多次。
<span v-for="n in 10">{{ n }}</span>
注意此处 n
的初值是从 1
开始而非 0
。
template
上的 v-for
与模板上的 v-if
类似,你也可以在 <template>
标签上使用 v-for
来渲染一个包含多个元素的块。例如:
<ul><template v-for="item in items"><li>{{ item.msg }}</li><li class="divider" role="presentation"></li></template>
</ul>
v-for与v-if
在vue风格指南中有一句话:Never use v-if
on the same element as v-for
.
不要将v-if和v-for使用在同一个元素上
vue解释了下面两种情况:
如果你想要
先过滤
一个列表,然后
决定列表中该元素是否显示
,可以这样做:
<template><ul v-for="currentValue in myArr"><li v-if="currentValue.isActive">{{ currentValue.myNumber }}</li></ul>
</template><script>
export default {data() {var myArr = [{myNumber:1,isActive:true},{myNumber:2,isActive:false},{myNumber:3,isActive:true},{myNumber:2,isActive:false}]return {myArr};}
};
</script>
控制台输出:1 3
如果你想要先决定
是否显示
一个列表,然后再进行过滤
,可以这样做:
<template><ul v-if="showList" ><li v-for="currentValue in myArr">{{ currentValue.myNumber }}</li></ul>
</template><script>
export default {data() {var showList = true;var myArr = [{myNumber:1,isActive:true},{myNumber:2,isActive:false},{myNumber:3,isActive:true},{myNumber:2,isActive:false}]return {myArr,showList};}
};
</script>
控制台输出:1 2 3 4
通过key管理状态
我们知道vue是有自己的响应式系统,大部分数据都是有响应式的功能,那么v-for中的数据应该也有响应式功能。也就是在v-for中的数据发生改变时,渲染出的列表也应该直接更新。
对于v-for的更新策略,vue的默认策略是“就近更新”,也就是不变动DOM的渲染顺序,而是直接改变渲染值。
我们来看两组代码:
不带key
<template><div ><p v-for=" (item,index) in keyTest" >{{ item.myName }} -------- <input type="text"></p><button @click="add()">添加</button></div>
</template><script>
export default {data() {var keyTest = [{id: 0,myName: 1,},{id: 1,myName: 2,},{id: 2,myName: 3,},{id: 3,myName: 4,},{id: 4,myName: 5,},];return {keyTest};},methods: {add(){this.keyTest.unshift({id:10,myName:'新的'});}},
};
</script>
带key
<template><div ><p v-for=" (item,index) in keyTest" >{{ item.myName }} -------- <input type="text"></p><button @click="add()">添加</button></div>
</template><script>
export default {data() {var keyTest = [{id: 0,myName: 1,},{id: 1,myName: 2,},{id: 2,myName: 3,},{id: 3,myName: 4,},{id: 4,myName: 5,},];return {keyTest};},methods: {add(){this.keyTest.unshift({id:10,myName:'新的'});}},
};
</script>
由效果图可以看出,带key之后插入元素不影响input中的值,而不带key时,只是在后面插入一个新DOM,之后修改之前的数据。
组件上使用v-for
等学完组件知识之后更新,暂存…
数组变化侦测
Vue可以侦听响应式数组的变更方法,前提是该方法会使数组变化。例如:
push()
在数组末尾插入一个值,并返回修改后的数组长度pop()
删除数组中最后一个值,并返回该值shift()
在数组第一个值之前插入一个值,并返回修改后的数组长度unshift()
删除数组中第一个值,并返回该值splice()
在数组中指定位置插入或删除元素sort()
对数组进行排序,并返回数组reverse()
颠倒数组中元素的位置
对数组操作时,有的方法会直接改变数组值,而有的方法会返回一个修改后的新数组(数组副本)。大部分过于方法只会返回一个新数组,我们可以将旧数组值使用新数组覆盖,并且vue实现了一些性能更高的DOM元素重用方法。