vue2中array的length生效与否

根据官方文档,相信都知道length方法为非响应式的。也可参考源码中src\core\observer\array.js,会发现并未对length进行处理。
image.png

而在实际中例子

1
2
3
4
5
6
<div id="app">
<ul>
<li v-for="item in gridData">{{item.name}}</li>
</ul>
<button @click="updateLength">更新</button>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
var app = new Vue({
el: "#app",
data: {
gridData: [
{
name: "Chuck Norris",
power: Infinity,
},
{
name: "Bruce Lee",
power: 9000,
},
{
name: "Jackie Chan",
power: 7000,
},
{
name: "Jet Li",
power: 8000,
},
],
},
methods: {
updateLength() {
this.gridData = [
{
name: "Chuck Norris",
power: Infinity,
},
{
name: "Bruce Lee",
power: 9000,
},
];
this.gridData.length = 0;
},
},
});

最终渲染的结果:列表是空的
image.png

修改updateLength

1
2
3
updateLength() {
this.gridData.length = 0;
}

最终渲染的结果:却是还是原来的4条。但data中gridData长度为0了
image.png

带着这个疑问,研究源码会发现:this.gridData =[{},{}]后,会触发当前组件的重新渲染,而重新渲染是个异步队列,在_l()中会对length进行重新取值,此时length的值已经是0了。

_l()对应的是renderList方法src\core\instance\render-helpers\render-list.js

对应的输入app.$options.render如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
with(this) {
return _c('div', {
attrs: {
"id": "app"
}
}, [_c('ul', _l((gridData), function (item) {
return _c('li', [_v(_s(item.name))])
}), 0), _v(" "), _c('button', {
on: {
"click": updateLength
}
}, [_v("更新")])])
}

image.png

image.png


vue2中array的length生效与否
https://yifengtingyu.cn/2022/11/22/vue2中array的length生效与否/
作者
依风听雨
发布于
2022年11月22日
许可协议