写点什么

【Vue3】 评论列表(简易)-- 思路与实现分析

作者:Sam9029
  • 2022 年 9 月 17 日
    四川
  • 本文字数:2617 字

    阅读完需:约 9 分钟

【Vue3】 评论列表(简易)-- 思路与实现分析

🦖我是 Sam9029,一个前端

Sam9029 的 InfoQ 主页:Sam9029 (infoq.cn)

**🐱‍🐉🐱‍🐉恭喜你,若此文你认为写的不错,不要吝啬你的赞扬,求收藏,求评论,求一个大大的赞!👍**


今日本想说些啥,想想无事,便不说些啥了,话不多说,直接上活

🐉源码实现

展示地址:Vue3小项目--评论列表 - 码上掘金 (juejin.cn)

效果展示:




🐉需求

  • 一级评论创建

  • 二级评论创建并关联一级评论

  • 二级评论的可控制展开与否

  • 评论时间戳-排序- (UNfinished)


全为本地数据操作



🐉源数据和接下来要创建的整合对象 格式皆为 数组包对象;

  [{},{},……]
复制代码


  • 源数据中 一级评论与二级评论 都在对象的同一属性层级(且有对应的不同 id)

  • 例子

  • 二级通过 parent_id 来关联 一级评论


[  { id: 1, nick_name: "冬天的雨", content: "非常好的文章!", parent_id: 0, time: 1625454585, boolChild: false },  { id: 16, nick_name: "用户9527", content: "收藏饿了", parent_id: 1, time: 1625454733, boolChild: false},  ……]
复制代码



🐉整体思路

🦊DOM 同一控制 评论 item 以及 评论 item HTML+CSS样式

  • 所有的 评论 item 都可以单独的作为一个 对象来考虑

  • 同理 新建评论的 输入框 也是一样

🦊根据原始数据 - 创建 新对象数组--整合对象

为什么创建整合对象

  • 便于渲染 评论列表

  • 介于评论 可以分为 一级 与 二级

  • 若有一个对象(整合对象) 同时包含 一二级的评论内容,即可放别统一管理相关联的一二级评论

  • 同时 用数组 来存储 所有的 对象(整合对象)

  • 同时要具备 响应式

实现

  • 通过侦听器(深度加立即侦听) 操作筛选 整合对象(对象) 以下内容

  • 引入 nanoid 给每个整合对象 唯一 id

  • 一级评论 parent (对象

  • 一级评论唯一

  • 二级评论 child (数组)

  • 可能有多个

  • 展开二级评论 控制 isShowChild(布尔值,默认值false)

  • 控制 二级评论的 回复展示


  • 整合对象json结构如下:

   [
     {
       itemId:''
       parent:{},
       chlid:[{},{}],
       isShowChild:false
     },
     ………
   ]

使用函数(updateCommentData)来 创建新的整合对象

  • 使用 update 意在更新,因为源数据可评论增加后会改变,单纯用创建来命名函数不太好

  • 同时可被监听器调用


源码


// 被渲染的数据 及`整合对象`let renderData = ref()
function updateCommentData(){ // 深拷贝 消除 影响源数据 let deepCloneOriginData = JSON.parse(JSON.stringify(originCommentListData.data))

// 筛出 一级评论 let parentData = deepCloneOriginData.filter(item => item.parent_id === 0) // 筛出 二级评论 let childData = deepCloneOriginData.filter(item => item.parent_id !== 0)
let newRenderData = []
for (let i = 0; i < parentData.length; i++) { newRenderData.push({ // 使用nanoid itemId:parentData[i].id, //parent为对象,且只有一个层级属性 使用浅拷贝 parent: {...parentData[i]}, //parent为数组包对象,有两个层级属性 使用深拷贝 child: JSON.parse(JSON.stringify(childData.filter(item=>item.parent_id===parentData[i].id))), isShowChild:false }) }
// renderData.value = JSON.parse(JSON.stringify(newRenderData))
// 测试输出 // console.log(JSON.parse(JSON.stringify(renderData.value)))
// 返回筛出数据 return 此场景可有可无 return newRenderData}
复制代码


关键解析:


  • 使用一级评论的 id 作为 新的对象的 id itemId:parentData[i].id

  • parent 为对象,且只有一个层级属性 使用浅拷贝 parent: {...parentData[i]},

  • parent 为数组包对象,有两个层级属性 使用深拷贝 child: JSON.parse(JSON.stringify(childData.filter(item=>item.parent_id===parentData[i].id))),

  • 展开二级评论 控制 isShowChild:false

侦听的实时更新变化数据

  • 源数据定义在 reactive 的 对象的属性 data 中


// 监听 并创建 新的渲染评论列表 数据watch(  ()=>originCommentListData.data,  updateCommentData,  {deep:true,immediate:true})
复制代码


  • updateCommentData 这时数据被侦听到变化时,执行的函数

  • 下一点阐述

  • {deep:true,immediate:true} 执行深度侦听与立即侦听(页面初始加载就执行一次)

🦊(一二级评论更新-新增后)的注意❗❗-(重点)

  • 一级评论新增直接 push 进源数据

  • 一级评论新增同样直接 push 进源数据

  • watch 监听 会 实时更新整合数据

  • 注意❗❗-此时问题出现,一级评论直接渲染,但是二级评论展开由isShowChild控制

  • 那新增 二级评论后 watch 整合对象实时更新的 isShowChild 会变成默认的 fasle, 此时执行 重新渲染,对应得(此前新增)二级就不会展开

  • 解决方式:

  • 将新增得二级评论所在得整合对象中的 itemid 在外面使用 响应式数据 存起来(levelTwoReControlId

  • 使用生命周期的更新函数 onUpdated (更新渲染完成后)

  • 读取更新后新的整合对象render 根据 levelTwoReControlId 找到对应得二级评论所在,改变其中的isShowChild为 true,之后清空levelTwoReControlId的值

  • 这样 解决决了 二级评论 新增后 (页面更新渲染)不展开二级评论的问题

🦊通过 函数控制 isShowChild 得布尔值变化

  • 绑定在回复

🦊源码注意事项!

整合对象 对象要用 ref 响应式 来存储

  • 因展开二级评论时,需要修改 isShowChild

  • 但是 要用 computed 监听原始数据并缓存结果 且不建议直接修改 computed 的值

不能直接修改 computed 的值

  • !!!computed 得到的属性 不要去直接操作了改变其值

  • 就是不能修改 computed 的值

深拷贝使用,隔绝创建的整合对象与源数据的影响

  • 因为对于 整合对象(上文有解释) 涉及操作,所以要隔绝引用地址的影响

  • 此处源数据 就是 数组包对象 (不复杂),使用 JSON 序列化(JSON.parse(JSON.stringify(Obj)))即可满足深拷贝的需求

时间毫秒转换

// 时间戳 转换 处理function timeToggle(_time){  let commentDate = new Date(_time)  let year = commentDate.getFullYear()  let month = commentDate.getMonth() + 1  let date = commentDate.getDate()  let commentClock = commentDate.toString().split(' ')[4]
return `${year}/${month}/${date} ${commentClock}`}
复制代码

🐉(待改进)

  • 评论 时间排序处理

  • 样式优化

  • 一二级评论新增函数合并


作为练手,项目还存在诸多不足待发现,后续持续改进



🦖我是 Sam9029,一个前端,坚信应无所往

文章若有错误,敬请指正🙏

**🐱‍🐉🐱‍🐉恭喜你,都看到这了,求收藏,求评论,求一个大大的赞👍!不过分吧**

Sam9029 的 InfoQ 主页:Sam9029 (infoq.cn)


发布于: 刚刚阅读数: 3
用户头像

Sam9029

关注

庸俗 2022.09.03 加入

好色

评论

发布
暂无评论
【Vue3】 评论列表(简易)-- 思路与实现分析_JavaScript_Sam9029_InfoQ写作社区