根据官方文档,相信都知道length方法为非响应式的。也可参考源码中src\core\observer\array.js,会发现并未对length进行处理。
而在实际中例子
<div id="app">
<ul>
<li v-for="item in gridData">{{item.name}}</li>
</ul>
<button @click="updateLength">更新</button>
</div>
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;
},
},
});
最终渲染的结果:列表是空的
修改updateLength
updateLength() {
this.gridData.length = 0;
}
最终渲染的结果:却是还是原来的4条。但data中gridData长度为0了
带着这个疑问,研究源码会发现:this.gridData =[{},{}]后,会触发当前组件的重新渲染,而重新渲染是个异步队列,在_l()中会对length进行重新取值,此时length的值已经是0了。
_l()对应的是renderList方法src\core\instance\render-helpers\render-list.js
对应的输入app.$options.render如下:
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("更新")])])
}