maomao1996 / Vue-mmPlayer

🎵 基于 Vue 的在线音乐播放器 Online music player
https://netease-music.fe-mm.com
MIT License
2.52k stars 764 forks source link

comment滚动加载有重复值 #110

Open jainnieh opened 7 months ago

jainnieh commented 7 months ago

这是我看的第一个完整的前端vue项目,可能因为我的知识点不够多, 没有思考完整. 如果是我知识点的缺漏, 请指出. 我在本地搭建前后端运行发现一个报错. 代码位于comment.vue中, 报错提示vue的v-for绑定的:key="item.commentId"重复:

// 滚动加载事件
    pullUp() {
      console.log('getComment')
      getComment(this.$route.params.id, this.page).then(({ comments }) => {
        this.commentList = [...this.commentList, ...comments]
        //测试输出
        console.log(this.commentList)
        console.log(comments)
      })
    }

我思考了原因, 如下: 以上逻辑应该是按照页数获取数据库中评论记录. 但是数据库中的记录会不断增加, 举个例子: 第一次加载评论数据库中[10, 9, 8, ...] 的前5条为[10, 9, 8, 7, 6] . 等第二次请求发出, 数据库可能出现新评论, 如果数据库更新为[11, 10, 9, 8, ...] ,此时请求第二页就得到[6, 5, 4, 3, 2], 显然两次请求中6重复了. pullUp()中使用 [...this.commentList, ...comments]进行合并, 应该不会过滤重复, 因为两个数组中都是放的对象, 对象检测的是地址值,不是内容.

jainnieh commented 7 months ago

我已经有了解决方案, 请参考:

 // 滚动加载事件
 pullUp() {
      console.log('getComment')
      getComment(this.$route.params.id, this.page).then(({ comments }) => {
        // 因为重复的部分是有规律的, 即已经获取的所有评论commentList最后的部分可能会和新请求的comments前面几个重复.
        //所以只要遍历可能重复的部分, 直到不再遇到重复就可以停止遍历
        let commentsLen = comments.length
        for (let i = 0; i < commentsLen; i++) {
          let originSearch = this.commentList.length - 1 - i
          if (comments[i].commentId === this.commentList[originSearch].commentId) {
            const duplicate = comments.shift()
            console.log('重复: ')
            console.log(duplicate)
            i--
            commentsLen--
          } else {
            break
          }
        }
        this.commentList = [...this.commentList, ...comments]
        console.log('@@@ 合并后: ')
        // 如果this.commentList.length不是30的倍数,则说明有重复的
        console.log(this.commentList.length)
        console.log(comments.length)
        console.log(this.commentList)
        console.log(comments)
      })
    }
jainnieh commented 7 months ago

好像可以先标记出重复, 然后截取comments. 我对js语法不太熟悉. 作者你可以看着进行优化