Javascript 通过参数化getter计算的Vue阵列不反应
我有一个包含评论数组的讨论对象列表,每个评论可以包含一个回复数组。我以这种方式显示讨论:Javascript 通过参数化getter计算的Vue阵列不反应,javascript,vue.js,vuex,Javascript,Vue.js,Vuex,我有一个包含评论数组的讨论对象列表,每个评论可以包含一个回复数组。我以这种方式显示讨论: <div v-for="comment in comments" v-bind:key="comment._id"> <Comment :itemId="itemId" :comment="comment" /> <Replies v-if="comment.replies.len
<div v-for="comment in comments" v-bind:key="comment._id">
<Comment :itemId="itemId" :comment="comment" />
<Replies v-if="comment.replies.length > 0" :itemId="itemId" :comment="comment" />
</div>
<Button value="Load more" @clicked="loadMoreComments(itemId)" />
当我点击载入更多评论按钮时,会出现新的评论。但是当我在回复中点击LoadMore按钮时,没有显示新的回复,尽管我可以在调试器中看到数组被放大了
Vuex存储子模块:
state: () => ({
discussion: {
incomplete: true,
comments: [],
},
comments: {},
}),
getters: {
DISCUSSION: state => state.discussion,
GET_COMMENT: state => id => state.comments[id],
GET_REPLIES: state => (comment) => {
if (comment.allShown) {
return comment.replies;
}
return comment.replies.slice(0, REPLY_LIMIT);
},
},
mutations: {
APPEND_COMMENTS: (state, payload) => {
const { comments, incomplete, userId } = payload;
state.discussion.incomplete = incomplete;
const commentIds = [];
comments.forEach(comment => processComment(state, comment, commentIds, userId));
state.discussion.comments = state.discussion.comments.concat(commentIds);
},
PREPEND_COMMENTS: (state, payload) => {
const { comments, userId } = payload;
const commentIds = [];
comments.forEach(comment => processComment(state, comment, commentIds, userId));
state.discussion.comments = commentIds.concat(state.discussion.comments);
},
SET_REPLIES: (state, payload) => {
console.log('SET_REPLIES');
const { commentId, replies, userId, replace } = payload;
const comment = state.comments[commentId];
if (!comment) {
return;
}
state.comments[commentId].showAll = true;
const commentIds = [];
replies.forEach(reply => processComment(state, reply, commentIds, userId));
if (!comment.replies || comment.replies.length === 0 || replace) {
state.comments[commentId].replies = commentIds;
} else {
state.comments[commentId].replies = comment.replies.concat(commentIds);
}
},
}
function processComment(state, comment, commentIds, userId) {
if (comment.replies) {
const repliesIds = [];
comment.replies.forEach((reply) => {
reply.voted = hasVoted(reply.votes, userId);
state.comments[reply._id] = reply;
repliesIds.push(reply._id);
});
comment.replies = repliesIds;
comment.allShown = comment.replies.length < REPLY_LIMIT;
} else if (!comment.parentId) {
comment.replies = [];
comment.allShown = false;
}
state.comments[comment._id] = comment;
commentIds.push(comment._id);
}
状态:()=>({
讨论:{
不完全:是的,
评论:[],
},
评论:{},
}),
吸气剂:{
讨论:state=>state.DISCUSSION,
获取注释:state=>id=>state.comments[id],
获取答复:state=>(comment)=>{
如果(注释.全部显示){
返回评论。回复;
}
返回comment.REPLY.slice(0,REPLY\u限制);
},
},
突变:{
附加注释:(状态、有效负载)=>{
const{comments,不完整,userId}=payload;
state.discussion.complete=不完整;
const commentId=[];
comments.forEach(comment=>processComment(state、comment、commentid、userId));
state.discussion.comments=state.discussion.comments.concat(commentId);
},
前置_注释:(状态,有效负载)=>{
const{comments,userId}=payload;
const commentId=[];
comments.forEach(comment=>processComment(state、comment、commentid、userId));
state.discussion.comments=commentId.concat(state.discussion.comments);
},
SET_回复:(状态,有效负载)=>{
console.log('SET_replays');
const{commentId,reply,userId,replace}=payload;
const comment=state.comments[commentId];
如果(!注释){
返回;
}
state.comments[commentId].showAll=true;
const commentId=[];
forEach(reply=>processComment(state,reply,commentid,userId));
如果(!comment.replays | | comment.replays.length==0 | |替换){
state.comments[commentId]。回复=commentId;
}否则{
state.comments[commentId]。repress=comment.repress.concat(commentId);
}
},
}
函数processComment(状态、注释、注释ID、用户ID){
如果(评论,回复){
常量repliesIds=[];
comment.reply.forEach((reply)=>{
reply.voated=hasvided(reply.voates,userId);
state.comments[reply.\u id]=回复;
repliesIds.push(reply.\u id);
});
comment.reples=replesids;
comment.allshow=comment.replays.length
完整的源代码如下:
以下是最小可复制代码沙盒:
我已经验证了这是由于带有参数的getter导致的。当我将应答放入静态数组以便使用无参数getter时,它开始工作
我遵循这项建议:
问题在哪里
更新:
有一种气味是变异
GET\u repress
,因为它对传递的对象起作用。因此,Vue没有机会检测到该对象来自该状态。因此我重写了它,只传递commentId并从状态加载注释,但它没有帮助。我建议您将showAll
替换为allshow
道具,并使用Vue.set
向comments
对象添加新键,因为Vue警告Vuex看不到新道具,请参见
您好,我也发现了这个拼写错误,但没有帮助。您的沙盒不工作,“无法读取未定义的属性‘slice’”。请更正我在answerVue.set(state.comments,comment.\u id,comment)末尾提到的GET_Responses调用;它是游戏规则的改变者,谢谢!
computed: {
comments() {
return this.$store.getters.DISCUSSION.comments.map(id => this.$store.getters.GET_COMMENT(id));
},
replies() {
return this.$store.getters.GET_REPLIES(this.comment).map(id => this.$store.getters.GET_COMMENT(id));
},
},
state: () => ({
discussion: {
incomplete: true,
comments: [],
},
comments: {},
}),
getters: {
DISCUSSION: state => state.discussion,
GET_COMMENT: state => id => state.comments[id],
GET_REPLIES: state => (comment) => {
if (comment.allShown) {
return comment.replies;
}
return comment.replies.slice(0, REPLY_LIMIT);
},
},
mutations: {
APPEND_COMMENTS: (state, payload) => {
const { comments, incomplete, userId } = payload;
state.discussion.incomplete = incomplete;
const commentIds = [];
comments.forEach(comment => processComment(state, comment, commentIds, userId));
state.discussion.comments = state.discussion.comments.concat(commentIds);
},
PREPEND_COMMENTS: (state, payload) => {
const { comments, userId } = payload;
const commentIds = [];
comments.forEach(comment => processComment(state, comment, commentIds, userId));
state.discussion.comments = commentIds.concat(state.discussion.comments);
},
SET_REPLIES: (state, payload) => {
console.log('SET_REPLIES');
const { commentId, replies, userId, replace } = payload;
const comment = state.comments[commentId];
if (!comment) {
return;
}
state.comments[commentId].showAll = true;
const commentIds = [];
replies.forEach(reply => processComment(state, reply, commentIds, userId));
if (!comment.replies || comment.replies.length === 0 || replace) {
state.comments[commentId].replies = commentIds;
} else {
state.comments[commentId].replies = comment.replies.concat(commentIds);
}
},
}
function processComment(state, comment, commentIds, userId) {
if (comment.replies) {
const repliesIds = [];
comment.replies.forEach((reply) => {
reply.voted = hasVoted(reply.votes, userId);
state.comments[reply._id] = reply;
repliesIds.push(reply._id);
});
comment.replies = repliesIds;
comment.allShown = comment.replies.length < REPLY_LIMIT;
} else if (!comment.parentId) {
comment.replies = [];
comment.allShown = false;
}
state.comments[comment._id] = comment;
commentIds.push(comment._id);
}
SET_REPLIES: (state, payload) => {
console.log("SET_REPLIES");
const { commentId, replies, userId, replace } = payload;
const comment = state.comments[commentId];
if (!comment) {
console.log(`Comment ${commentId} not found`);
return;
}
state.comments[commentId].allShown = true;
// state.comments[commentId].showAll = true;
...
function processComment(state, comment, commentIds, userId) {
if (comment.replies) {
const repliesIds = [];
comment.replies.forEach(reply => {
Vue.set(state.comments, reply._id, reply);
// state.comments[reply._id] = reply;
repliesIds.push(reply._id);
});
comment.replies = repliesIds;
comment.allShown = comment.replies.length < 3;
} else if (!comment.parentId) {
comment.replies = [];
comment.allShown = false;
}
Vue.set(state.comments, comment._id, comment);
// state.comments[comment._id] = comment;
commentIds.push(comment._id);
}
computed: {
replies() {
return this.$store.getters
.GET_REPLIES(this.comment) // passing comment itself instead of its id
.map(id => this.$store.getters.GET_COMMENT(id));
}
},