一、问题
在Fastmock上mock数据,通过axios发送get请求数据存放到数组中,控制台可以打印出来,但就是渲染不上去,不知道什么原因
Vue代码如下:
<template>
<div>
<ul>
<li v-for="(item, index) in nameArr" :key="index">{{ item }}</li>
</ul>
{{ nameArr }}
</div>
</template>
<script>
import axios from "axios";
export default {
data() {
return {
baseUrl:
"https://www.fastmock.site/mock/a2de7b065c65387ab6c6ab6b5fe95086/lsj/api/test",
nameArr: [],
};
},
mounted() {
axios.get(this.baseUrl).then((res) => {
for (var i = 0; i < 10; i++) {
var myData = JSON.parse(JSON.stringify(res.data));
this.nameArr[i] = myData.info[i].name;
console.log(this.nameArr[i]);
}
});
},
};
</script>
<style>
</style>
截图:
控制台明明都可以打印出来,但就是渲染不上
二、原因
由于 JavaScript 的限制,Vue 不能检测数组和对象的变化。
具体内容查看官网解释:Vue官网-深入响应式原理
2.1 对于对象:
Vue 无法检测 property 的添加或移除。由于 Vue 会在初始化实例时对 property 执行 getter/setter 转化,所以 property 必须在 data 对象上存在才能让 Vue 将它转换为响应式的
var vm = new Vue({
data:{
a:1
}
})
// `vm.a` 是响应式的
vm.b = 2
// `vm.b` 是非响应式的
解决:
- 可以使用
Vue.set(object, propertyName, value)
方法向嵌套对象添加响应式 property。
Vue.set(vm.someObject, 'b', 2)
- 还可以使用 vm.$set 实例方法,这也是全局 Vue.set 方法的别名:
this.$set(this.someObject,'b',2)
2.2 对于数组:
当使用索引直接设置一个数组项时,例如:vm.items[index] = newValue
,Vue 无法检测数组的变动。
var vm = new Vue({
data: {
items: ['a', 'b', 'c']
}
})
vm.items[1] = 'x' // 不是响应性的
解决:
1.Vue.set() 方法
// Vue.set
Vue.set(vm.items, indexOfItem, newValue)
也可以使用 vm.$set
实例方法,该方法是全局方法 Vue.set
的一个别名:
vm.$set(vm.items, indexOfItem, newValue)
2.数组方法
Vue对被侦听的数组的变更方法进行了包裹,所以可以触发视图更新
[直接修改]
-
数组尾部操作
- push() - 向数组末尾添加一个或多个元素,并返回新的长度
- pop() - 删除并返回数组的最后一个元素
-
数组头部操作
- shift() - 删除并返回数组的第一个元素
- unshift() - 向数组开头添加一个或多个元素,并返回新的长度
-
数组其他操作
-
splice() - 数组插入与删除,
arr.splice(index, howmany, item1,...,itemx)
-
sort() - 数组排序(按照字符编码的顺序)
-
reverse() - 数组翻转
-
join() - 数组转字符串,参数为分隔符,默认以逗号
,
分割
-
[需返回值替换原数组]
- filter()
- concat()
- slice()
源代码修改为:
axios.get(this.baseUrl).then((res) => {
for (var i = 0; i < 10; i++) {
var myData = JSON.parse(JSON.stringify(res.data));
this.$set(this.nameArr, i, myData.info[i].name);
//或:this.nameArr.push(myData.info[i].name)
console.log(this.nameArr[i]);
}
});