当你在用Vue开发的时候,你可能不经常,只是偶尔地遇到,“哎?我明明把异步数据赋值给我定义的数组变量或者对象变量了,为什么页面上数据还是老旧的并没有改变呢?”,这时候你可能各种尝试,比如把生命周期函数
mounted()
更改为created()
,于是数据的重新绑定直接被你提前到new Vue()
节点;或者你在你的数据重新赋值之前插入个alert()
,直接粗暴触发更新检测,但明显我们不允许在页面中出现这个;又或者机智地使用个setTimeout(function(){},0)
,但多测试几次,你会发现,我根本控制不了这个定时器是否一定触发,这特么到底是为什么。终于,碰了几次南墙,你想回头,(怎么可能,你必须解决这个问题,项目必须完成的呀!),所以寻求其他种种方法,绕过了这堵高墙,然后心虚地告诉自己终于解决了,但你根本不知道这里面埋了什么隐患,就等着项目交付的时候全部爆发了。好了,吹牛逼到此结束,老套路,先重现错误:HTML
<template>
<ul>
<li v-for="data in formData" :key="data.id">
name: {{data.name}},age: {{data.age}}
</li>
</ul>
</template>
JavaScript
<script>
export default {
name: 'inspection',
data() {
return {
formData: [{
id: 1,
name: 'zhangsan',
age: 20
},{
id: 2,
name: 'lisi',
age: 21
},{
id: 3,
name: 'wangwu',
age: 22
}]
}
},
mounted() {
this.formData[0] = {
id: 4,
name: 'zhaoliu',
age: 23
};
}
}
</script>
(style在这里就不做显示了)
呐,下面就是结果啦:
简直是丝毫不给面子啊!所以这是为什么,你想啊,数据都挂载渲染上去了,写在
mounted()
里还有啥用,当然凉凉,你完全可以写在created()
里,但是如果这是异步数据呢???我们凭什么保证在某个生命周期内就拿到数据,不可能的!5G都不可能的!那么怎么解决?!把目光投向Object.defineProperty()
,这可是原生js的方法,牛逼的很呢!Vue的更新检测就靠这玩意操作setter()
、getter()
了。所以,怎么用才能随时随地触发这类数据的更新检测?官方文档给出了明确的方法,这里直接看成功示例:HTML
<template>
<ul>
<li v-for="data in formData" :key="data.id">
name: {{data.name}},age: {{data.age}}
</li>
</ul>
</template>
JavaScript
<script>
import Vue from 'Vue'
export default {
name: 'inspection',
data() {
return {
formData: [{
id: 1,
name: 'zhangsan',
age: 20
},{
id: 2,
name: 'lisi',
age: 21
},{
id: 3,
name: 'wangwu',
age: 22
}]
}
},
mounted() {
Vue.set(this.formData, 0 , {id: 4, name: 'zhaoliu', age: 23});
// this.formData.splice(0, 1, {id: 4, name: 'zhaoliu', age:23});
}
}
</script>
好啦,这就成功触发Vue的更新检测啦!当然你完全可以用数组的变异方法来触发:push()
pop()
shift()
unshift()
splice()
sort()
reverse()
提示(Tips):你无法直接替换数组项,但是你完全可以不像本文这样主动触发而改变数组项里面的属性值。关于对象,你也只是不能直接新增、删除一个键值对,但你完全可以改变其中的属性值