VUE:v-for的使⽤及源码
⼀、前⾔
v-for可以说是vue中使⽤最多的指令之⼀,不过,你真的了解它吗?v-for不仅仅能⽤于遍历数组,也不仅仅能⽤于遍历对象。
⼆、使⽤
先说结论:v-for可以遍历数组、对象、数字以及字符串,以及,在vue3版本新增的对于部署了iterator接⼝的对象的⽀持。下⾯是各种场景的分析,以(item,index) in obj的使⽤⽅式为例:
<div v-for="(item,index) in obj"></div>
1.遍历数组
遍历数组时,item是数组的当前项,index是对应的下标
//(item,index) in [1,2,3]
// item : 1 2 3
// index: 0 1 2
2.遍历对象
遍历对象时,item是对象键值对的value,index是对应的key
遍历顺序,和Object.keys(obj)、Object.values(obj)的遍历顺序是⼀样的,即先是数值键,按升序遍历;然后是字符串键,按加⼊时间遍历;然后是Symbol键,按加⼊时间遍历
// obj = {
// 1: 1,
// v: 2,
// c: 3,
// };
//(item,index) in obj
// item : 1 2 3
// index: 1 v c
3.遍历字符串
item是字符串的每个字符,index是对应的下标
typeof array// (item,index) in 'abc'
// item: a b c
// index: 0 1 2
4.遍历数字
遍历数字n时,item是从1到n的数字,index是对应的顺序,以0为起始值(可以理解为遍历从1到n的数组)
// (item,index) in 3
// item: 1 2 3
// index: 0 1 2
5.遍历有interator接⼝的对象
iterator接⼝,不明⽩的可以查阅阮⼀峰⽼师的es6标准⼊门,
⽐如Set、Map、classList等等
v-for在遍历这类对象时,会先⽤Array.from将这些对象转换为数组,然后就和遍历数组类似的了
// const set = new Set([3, 4, 5]);
// (item,index) in set
// item: 3 4 5
// index: 0 1 2
// const map = new Map();
// map.set(1,2)
// map.set(3,4)
/
/ map.set(5,6)
// (item,index) in map
// item: [1,2] [3,4] [5,6]
// index: 0 1 2
三、源码
这⾥放下源码(位于core/instance/render-helpers/render-list.js⽂件内),源码看起来很容易理解,就不多说了,其实就是对各种情况的处理。(这⾥放的是vue3版本的远吗,vue2版本的,没有对iterator做特殊处理,所以vue2版本的v-for也不能⽤于遍历Set、Map等)
function renderList(source, renderItem) {
let ret;
if (isArray(source) || isString(source)) {
ret = new Array(source.length);
for (let i = 0, l = source.length; i < l; i++) {
ret[i] = renderItem(source[i], i);
}
}
else if (typeof source === 'number') {
ret = new Array(source);
for (let i = 0; i < source; i++) {
ret[i] = renderItem(i + 1, i);
}
}
else if (isObject(source)) {
if (source[Symbol.iterator]) {
ret = Array.from(source, renderItem);
}
else {
const keys = Object.keys(source);
ret = new Array(keys.length);
for (let i = 0, l = keys.length; i < l; i++) {
const key = keys[i];
ret[i] = renderItem(source[key], key, i);
}
}
}
else {
ret = [];
}
return ret;
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论