笔者在获取数据或修改数据后,有时会出现部分数据显示,部分数据不显示的情况。出现这种情况,大概率是非响应式数据的关系。
1.如何确定非响应式数据
确定是否为非响应式数据很简单,只需要在打印中查看即可
如图,现在看来orderNo的值为(...),且点击(...)后,真实数据才会显示出来,这种就是响应式对象,而refUserName直接显示了数据,这种就是非响应式对象。
当然还可以看get和set,响应式对象都配备了get和set,非响应式对象则没有。
2.解决非响应式对象转变为响应式对象的问题
<script>
data(){
return {
rows:[]
}
},
methods:{
loadData() {
$.post("/F4038/ajax1", {
searchArgs: JSON.stringify(this.searchArgs),
}, r => {
this.rows = r.data;
setTimeout(()=>{
$.get("/F4038/ajax2",r => {
let dicts = r.data
const dictionary = {};
dicts.forEach((dict) => {
dictionary[dict.orderNo] = dict.refUserName;
});
//遍历rows,在row中添加refUserName属性
this.rows.forEach((row)=>{
row.refUserName = dictionary[row.orderNo]
})
})
},300)
})
}
}
<script>
笔者先描述一下自己遇到的问题,loadData函数向后端发送请求rows数据,但是现在又新需求,需要在rows中一个个对象中,添加一个refUserName,且后端需要新请求,既前端发送新请求去请求后端的refUserName,添加到rows中。
2.1使用$set生成响应式对象
在一个响应式对象中,直接添加数据,会导致这个数据不是响应式的,这也是笔者犯得错误。我们可以使用this.$set(item,key,value)来添加一个响应式对象。
item为你添加数据的对象,key为对象中要增加或修改的数据的键,value为与键相应的值。
所以通过this.$set(),笔者将修改自己的代码。
修改前的代码:
//修改前的代码
this.rows.forEach((row)=>{
row.refUserName = dictionary[row.orderNo]
})
修改后的代码:
//修改后代码,refUserName已经为响应式对象
this.rows.forEach((row)=>{
this.$set(row,'refUserName',dictionary[row.orderNo])
})
2.2 未返回值赋初值 以生成响应式对象
大家可以看到,this.rows = r.data 也是赋值操作,但是这次却生成的全部是响应式对象,这是为什么?因为对象第一次赋值,生成的就是响应式对象,但后面增加的数据就都不是响应式对象了。通过这一特性,我们不妨在this.rows拿到数据前就手动为r.data赋值,第一次的拿到的r.data没有refUserName这个属性,我们手动为其添加,这样this.rows第一次拿到数据,已经有refUserName这个属性,自然而然就生成了响应式对象
//this.rows第一次拿到的数据中没有refUserName,自然不会为refUserName生成响应式对象
...
r => {
this.rows = r.data;
...
}
修改后代码
//this.rows第一次拿到的数据中存在refUserName,会为refUserName生成响应式对象
...
r => {
r.data.map((row)=>{
row.refUserName = ""
})
this.rows = r.data;
...
}
代码修改后,我们后面就可以直接从后端拿到值,并直接赋给rows的子对象,而不使用this.$set()
3.结束语
前端新手分享自己做项目时的问题,如有错误,请各位大佬指教!