事情是这样的:
- 前端需要在页面渲染之前使用 axios获取一个 数组 类型的数据
- 但获取后,样式出现了错误,不是预期的那样
- 控制台报错 数组undefined
思路与解决:
vue 在 created 方法中使用 axios 请求数据,虽然是在 created 方法中发出的请求与后续处理,
created(){
axios.get(...).then(res => { res.data .....});
}
但是 axios 是异步的,created 方法执行完后,axios 或许因为网络延迟 或 数据量太大,而延后获取。而 created 方法执行后,就开始了渲染工作了,使得 单向绑定、插值表达式 等的数据为 undefined ,这里简单举个例子:
<div>
<img v-for="item in arrays" :src=item class="img"></img>
</div>
<script>
const App = {
data(){
return { arrays: [] } // 图片
},
created(){
axios.get(...).then(res => { this.arrays = res.data;});
}
}
Vue.createApp(App).mount('#app');
</script>
如果出现网络延迟、数据大,那么 arrays 就是 undefined。
所以,我们可以使用 v-if 给标签设置一个状态,比如 status, 最开始 status 为 false,当 axios 获取到数据后为 true ,举例:
<div v-if="this.status">
<img v-for="item in arrays" :src=item class="img"></img>
</div>
<script>
const App = {
data(){
return {
arrays: [] ,
status: false
} // 图片
},
created(){
axios.get(...).then(res => {
this.arrays = res.data;
this.status = true;
});
}
}
Vue.createApp(App).mount('#app');
</script>
这样,当数据拿到后,vue渲染时,数据就不是 undefined 了。
如果你的页面只使用了vue,没有使用 jQuery,那看到这里就够了,接下来是 jQuery的问题。
由于页面使用了 jQuery 去操作上述的 img 标签的样式,jQuery 需要获取图片的数量,也就是 img 标签的个数,如果再 head 标签中进行操作,就会出现错误
<head>
<script src="./js/jquery-3.6.0.min.js"></script>
<script src="./js/handleImage.js"></script>
<script>
$(document).ready(function() {
handleImage();
}
</script>
</head>
我们知道 vue 操作的是虚拟dom节点,jQuery 操作真实的 dom 元素,这就使得 jQuery 的执行要优先于 vue,所以 jQuery 的 ready 方法就会很快执行,使得 操作 img 数组出现错误。
解决办法: 就是将 使用 jQuery 的方法放到 vue 后面执行,如下:
<head>
<script src="./js/jquery-3.6.0.min.js"></script>
</head>
<div v-if="this.status">
<img v-for="item in arrays" :src=item class="img"></img>
</div>
<script>
const App = {
data(){
return {
arrays: [] ,
status: false
} // 图片
},
created(){
axios.get(...).then(res => {
this.arrays = res.data;
this.status = true;
});
},
mounted(){
// 休息1s
for(var t = Date.now();Date.now() - t <= 1000;);
}
}
Vue.createApp(App).mount('#app');
</script>
<script src="./js/handleImage.js"></script>
<script>
$(document).ready(function() {
handleImage();
}
</script>
script 是从上往下执行,当 vue 挂载完毕后,真实的dom也渲染好了,再使用 jQuery 操作 dom 就没问题了。
并且,mounted 方法休息了1秒,确保jQuery能拿到正确的数据