我有一个屏幕,将其主要数据部分划分为多个选项卡,希望每个选项卡都位于其自己的组件上。
但是,由于某些原因,第一次渲染时数据没有显示在组件上。关键是,如果单击按钮刷新数据,则加载的数据就很好。无论哪种方式我都没有收到错误消息,所以我认为我一定在误解了VueJS生命周期。
const CommentScreen = {
props: {
accountid: {
type: Number,
required: true
}
},
template: `
<div>
<CommentForm
v-on:commentsupdated="comments_get"
v-bind:accountid="accountid"
></CommentForm>
<v-btn round color="primary" v-on:click="comments_get" dark>Refresh Comments</v-btn>
<v-data-table
:headers="commentheaders"
:items="comments"
hide-actions>
<template slot="items" slot-scope="props">
<td>{{ props.item.entrydate }}</td>
<td>{{ props.item.entryuserforename + " " + props.item.entryusersurname }}</td>
<td>{{ props.item.comment }}</td>
</template>
</v-data-table>
</div>
`,
components: {
'CommentForm': CommentForm
},
data(){
return {
commentheaders:[
{ text:'Entry Date', value:'entrydate' },
{ text:'Entry User', value:'entryuserforename' },
{ text:'Comment', value:'comment' }
],
comments:[]
}
}
,
mounted() {
this.comments_get();
},
methods:{
comments_get(){
let url = new URL('/comments/', document.location);
url.searchParams.append('accountid',this.accountid);
let options = {
method: 'GET',
mode: 'cors',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json;charset=UTF-8'
}
};
self = this;
fetch(url, options)
.then(
response => {
if (response.status === 401) {
self.$root.$emit('notloggedin');
} else if (response.status === 403) {
self.$root.$emit('displayalert','Missing Permission: View Comments');
} else if (response.status === 204) {
self.comments = [];
} else if(!response.ok) {
response.json()
.then(data => self.$root.$emit('displayalert', data.errors))
.catch(error => self.$root.$emit('displayalert', error.status + ' ' + error.statusText));
} else {
response.json()
.then(data => self.comments = data.comments)
.catch(error => self.$root.$emit('displayalert', error));
}
}
)
.catch(error => self.$root.$emit('displayalert', error));
}
}
};
请原谅上面存储的代码量,我不确定我可以删除/应该删除什么以使问题更简短。
任何人都可以告诉我第一次加载该组件时如何自动加载数据吗?
非常感谢。
答案 0 :(得分:0)
mounted
钩子是async
,这使这种操作很棘手。
与您尝试执行的操作类似的示例。
new Vue({
el: "#app",
data: {
placeId: 1,
sight: "",
sightImages: [],
slideIndex: 1
},
mounted() {
var self = this;
fetch(`https://jsonplaceholder.typicode.com/albums/${this.placeId}/photos?_start=1&_end=10`)
.then(response => {
if (response.ok) {
return response;
} else {
if (response.status === 401) {
alert("401");
//self.$root.$emit("notloggedin");
}
if (response.status === 403) {
alert("403");
//self.$root.$emit("displayalert", "Missing Permission: View Comments");
}
if (response.status === 204) {
alert("204");
//self.comments = [];
}
}
})
.then(response => response.json())
.catch(error => {
console.log("ERROR " + error);
})
.then(data => {
self.sight = {
id: data[0].albumId
};
self.sightImages = data;
})
/** IF YOU REMOVE THIS THINGS WONT WORK RIGHT */
.then(() => {
self.showSlides(self.slideIndex);
});
/** */
},
methods: {
showSlides(n) {
let i;
let slides = document.getElementsByClassName("mySlides");
let dots = document.getElementsByClassName("demo");
let captionText = document.getElementById("caption");
if (n > slides.length) {
this.slideIndex = 1;
}
if (n < 1) {
this.slideIndex = slides.length;
}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
for (i = 0; i < dots.length; i++) {
dots[i].className = dots[i].className.replace(" active", "");
}
console.log(slides[0]);
console.log(document.getElementsByClassName("mySlides").length);
slides[this.slideIndex - 1].style.display = "block";
dots[this.slideIndex - 1].className += " active";
captionText.innerHTML = dots[this.slideIndex - 1].alt;
},
plusSlides(n) {
this.showSlides((this.slideIndex += n));
},
currentSlide(n) {
this.showSlides((this.slideIndex = n));
}
},
});
.demo-cursor {
width: 3% !important;
cursor: pointer;
margin: 0px 2px
}
.sight-photos {
width: 6%;
}
.row {
display: inline-block;
}
.cntrlbtn {
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>
<div id="app">
<div class="wrapper">
<div class="sight-container">
<p class='sight-name'>Sight Id: {{ sight.id }}</p>
<div class="photos-container">
<div v-for='(image, index) in sightImages' class="mySlides">
<div class="numbertext">{{ index + 1 }} / {{ sightImages.length }}</div>
<img class='sight-photos' :src="image.thumbnailUrl">
</div>
<a class="cntrlbtn" @click='plusSlides(-1)'>❮</a>
<a class="cntrlbtn" @click='plusSlides(1)'>❯</a>
<div class="caption-container">
<p id="caption"></p>
</div>
<div class="row">
<img v-for='(image, index) in sightImages' class="demo-cursor" :src="image.url" @click="currentSlide(index + 1)">
</div>
</div>
</div>
</div>
</div>
您可以尝试以下操作:
const self = this;
fetch(url, options)
.then(response => {
if (response.ok) {
return response;
} else {
if (response.status === 401) {
self.$root.$emit("notloggedin");
}
if (response.status === 403) {
self.$root.$emit("displayalert", "Missing Permission: View Comments");
}
if (response.status === 204) {
self.comments = [];
}
}
})
.then(response => response.json())
.catch(error => {
self.$root.$emit("displayalert", error);
})
.then(data => {
self.comments = data.comments;
});
答案 1 :(得分:0)
我知道了!
代码问题在下面的行中:
self = this;
在第一次运行代码时(而且是第一次),它在寻找错误的上下文。替换为
let self = this;
问题已经解决。
我有时讨厌计算机,它们总是按照我的意思而不是我的意思!