在我的Vue.js SPA项目中,我有一个类似Instagram的图像板。这是一个全栈项目,后端是express.js postgresSQL。每当用户点击一个图像时,一个模态就会打开,显示该图像和其他用户对该图像的评论。用户可以使用模态内的下一个/上一个按钮导航到下一个/上一个图像,并且相应地将出现对新图像的注解。
modal是主app.js中的一个组件。在模态组件中还有一个用于用户注解的组件。
一切都很完美,就像上面描述的那样。突然,在没有接触或修改任何代码的情况下,有些东西坏了:现在当用户使用下一个/上一个按钮在图像之间导航时,新图像出现,但是旧图像的注解保持不变,而不显示与新图像相关的注解。
- 如果我不使用下一个/上一个按钮导航,而是关闭模态并单击另一个图像,我将获得该图像的相关评论。
我检查和检查我的代码太长了,现在不能弄清楚哪里出了问题,更奇怪的是,它的工作和突然停止工作。有没有人有过类似的案例或者知道是什么导致这种情况的?是否与服务器有关?
app.js
import * as Vue from "./vue.js";
import modalComponent from "./modal-component.js";
Vue.createApp({
data() {
return {
name: "images",
images: [],
imgClicked: "",
imagePath: "",
moreButton: true,
imageSelected: false,
userInput: { username: "", description: "", title: "" },
formNotValid: false,
errorMsg: false,
isMobile: false,
};
},
mounted() {
console.log(window.innerWidth);
history.pushState({}, "", "/home");
this.imagePath = "";
this.imageRemoved = false;
this.errorMsg = false;
fetch("/image_board")
.then((res) => res.json())
.then((data) => {
this.images = data;
console.log("fetched-data: ", data);
});
window.addEventListener("popstate", () => {
let path = location.pathname.slice(1);
if (path != "") {
path = Number.parseInt(path);
if (Number.isNaN(path)) {
history.replaceState({}, "", "/");
} else {
this.idCard = path;
}
} else {
this.imgClicked = "";
}
});
},
components: {
"modal-component": modalComponent,
},
methods: {
......
updateImg(newRenderedImgId) {
this.imgClicked = newRenderedImgId;
history.pushState({}, "", `/${this.imgClicked}`);
},
},
}).mount("#app_container");
/************************************************/
index.html
<modal-component v-if=“imgClicked”v-bind:selected-Img=“imgClicked”@update=“updateImg”@close=“closeModalComponent”>
”
/************************************************/
modal-component.js
import commentsComponent from "./comments-component.js";
const modalComponent = {
data() {
return {
header: "modal-component",
img: {},
rendernNextBtn: true,
renderPreviousBtn: true,
nextImgOnScreen: null,
previousImgOnScreen: null,
};
},
props: ["selectedImg"],
components: {
"comments-component": commentsComponent,
},
mounted() {
this.fetchData();
},
watch: {
selectedImg: function () {
this.fetchData();
this.img.id = this.img.nextId || this.img.previousId;
},
},
methods: {
fetchData() {
console.log("this.selectedImg: ", this.selectedImg);
this.rendernNextBtn = true;
this.renderPreviousBtn = true;
fetch(`/image_board/${this.selectedImg}`)
.then((res) => res.json())
.then((data) => {
this.img = data;
if (this.img.previousId === null) {
this.renderPreviousBtn = false;
}
if (this.img.nextId === null) {
this.rendernNextBtn = false;
}
})
.catch((err) => {
console.log("error: problem fetching data: ", err);
});
},
close() {
this.$emit("close");
},
nextImgId() {
console.log(this.img.nextId);
this.$emit("update", this.img.nextId);
},
previousImgId() {
console.log(this.img.previousId);
this.$emit("update", this.img.previousId);
},
},
template: `
<div class="modal_wrapper_div">
<div class="modal_component_div">
<div class="span_x_div">
<span @click="close" class=close-tag>x</span>
</div>
<div class="modal_img_div">
<div class="next_previous_img_div">
<div v-if="renderPreviousBtn" @click="previousImgId" class="previous_div">
<span>«</span>
</div>
<div v-if="rendernNextBtn" @click="nextImgId" class="next_div">
<span>»</span>
</div>
</div>
<img v-bind:src="img.url" v-bind:alt="img.title" v-bind:key="img.id"/><br/>
</div>
<div class="user_details_div">
<div class="user_details_container">
<div class="img_title_wrapper">
<h3>{{img.title}}</h3>
</div>
<div class="user_details_par_container">
<p class="uploaded_by_par">Uploaded By:<br>{{img.username}}, {{img.created_at}}</p><br>
<p class="decription_par">Description:<br>{{img.description}}</p>
</div>
</div>
<comments-component v-bind:img-id="selectedImg"></comments-component>
</div>
</div>
</div>`,
};
export default modalComponent;
/****************************************************/
comments-component.js
const commentsComponent = {
data() {
return {
comments: [],
username: "",
comment: "",
};
},
props: ["imgId"],
mounted() {
fetch(`/comments/${this.imgId}`)
.then((res) => res.json())
.then((fetchedData) => {
console.log(
"FETCHED DATA: comments are retreived",
fetchedData
);
this.comments = fetchedData;
})
.catch((err) => {
console.log("ERROR: PROBLEM TO FETCH DATA ", err);
});
},
methods: {
handleCommentSubmit(e) {
e.preventDefault();
fetch("/comment", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
comment: this.comment,
username: this.username,
image_id: this.imgId,
}),
})
.then((res) => res.json())
.then((data) => {
this.comments.unshift(data.payload);
this.username = "";
this.comment = "";
})
.catch((err) => {
"Error fetch comments: ", err;
});
},
},
template: `
<div class="comments_component_div">
<div class="comments_form_div">
<form class="comments_form">
<input class="username_input" v-model='username' type="text" name="username" placeholder="User Name">
<textarea class="comment_input" v-model='comment' id="commentbox" type="text" name="comment" placeholder="Add Your Comment..." cols="30" rows="10"></textarea>
<button class="comments_button" @click="handleCommentSubmit">Add Comment</button>
</form>
</div>
<div class="single_comment_box" v-if="comments.length" v-for="comment in comments" :key="comment.id">
<div class="list_item">
<p id="username_par">{{comment.username}}:</p>
<p id="comment_par">{{comment.comment}}</p>
</div>
</div>
</div>`,
};
export default commentsComponent;
1条答案
按热度按时间mbzjlibv1#
看起来CommentsComponent在挂载时只加载注解一次。如果
imgId
发生更改,则需要再次加载注解。您可以在该属性上将挂载的替换为渴望的监视器:我不能告诉你为什么它以前工作。