Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/436.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 通过参数化getter计算的Vue阵列不反应_Javascript_Vue.js_Vuex - Fatal编程技术网

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));
    }
  },