当我向api发送请求并将结果呈现为列表时,某些图像显示较晚,而文本首先显示。有什么办法可以防止这种情况?
我只想在逻辑上完全完成图像,类,文本的计算时显示列表。如果它们还没准备好,我还是要隐藏它们。 v-cloak 无法正常工作!。
这是我遇到麻烦的部分。
您可以看到,还渲染了整个列表,还剩下一些图像。
这是我的代码示例。
<div id="app">
<h2>Todos:</h2>
<ol>
<li v-for="todo in todos">
<!-- thre may be some more logics -->
<img :src="todo.img" width="100px">
{{todo.name}}
</li>
</ol>
</div>
new Vue({
el: "#app",
data: {
todos: []
},
created: function(){
this.requestApi();
},
methods: {
requestApi(){
this.todos = [
{ img: "https://steamcdn-a.akamaihd.net/apps/dota2/images/mars/hero_mars93fd33s5.jpg", name: "AAA" },
{ img: "https://steamcdn-a.akamaihd.net/apps/dota2/images/mars/hero_mars93fd33s5.jpg", name: "BBB" },
{ img: "https://steamcdn-a.akamaihd.net/apps/dota2/images/mars/hero_mars93fd33s5.jpg", name: "CCC" },
{ img: "https://steamcdn-a.akamaihd.net/apps/dota2/images/mars/hero_mars93fd33s5.jpg", name: "DDD" }
];
}
}
})
https://jsfiddle.net/vxy4gnj8/3/
在jsfiddle上面没有清楚显示我的问题,因为它没有发送到真实的api且渲染速度太快。
答案 0 :(得分:1)
您可以使用v-if
仅在requestApi
完成时显示组件:
<div id="app">
<div v-if="!isLoading">
<h2>Todos:</h2>
<ol>
<li v-for="todo in todos">
<!-- thre may be some more logics -->
<img :src="todo.img" width="100px">
{{todo.name}}
</li>
</ol>
</div>
</div>
new Vue({
el: "#app",
data: {
todos: [],
isLoading: true
},
created: function(){
this.requestApi();
},
methods: {
requestApi(){
this.todos = [
{ img: "https://steamcdn-a.akamaihd.net/apps/dota2/images/mars/hero_mars93fd33s5.jpg", name: "AAA" },
{ img: "https://steamcdn-a.akamaihd.net/apps/dota2/images/mars/hero_mars93fd33s5.jpg", name: "BBB" },
{ img: "https://steamcdn-a.akamaihd.net/apps/dota2/images/mars/hero_mars93fd33s5.jpg", name: "CCC" },
{ img: "https://steamcdn-a.akamaihd.net/apps/dota2/images/mars/hero_mars93fd33s5.jpg", name: "DDD" }
];
this.isLoading = false
}
}
})
请注意,isLoading
用作检查请求是否完成的标志。
答案 1 :(得分:1)
requestApi(){
const vm = this;
const list = [
{ img: "https://steamcdn-a.akamaihd.net/apps/dota2/images/mars/hero_mars93fd33s5.jpg", name: "AAA" },
{ img: "https://steamcdn-a.akamaihd.net/apps/dota2/images/mars/hero_mars93fd33s5.jpg", name: "BBB" },
{ img: "https://steamcdn-a.akamaihd.net/apps/dota2/images/mars/hero_mars93fd33s5.jpg", name: "CCC" },
{ img: "https://steamcdn-a.akamaihd.net/apps/dota2/images/mars/hero_mars93fd33s5.jpg", name: "DDD" }
];
Promise.all(
list.map(item=>new Promise((resolve,reject)=>{
const img = new Image();
img.addEventListener("load",function(){
// here this means the img element
this.__isOK__ = true;
resolve(this);
},{once:true})
img.addEventListener("error",function(){
this.__isOK__ = false;
resolve(this);
},{once:true});
img.src = item.img;
}))
).then(arr=>{
const success = arr.filter(img=>img.__isOK__);
console.log(`Finish. We had loaded ${arr.length} pictures. ${success.length} of them was successed`);
vm.todos = list;
})
}