Laravel5.4+Vuejs 实现嵌套评论

此Demo中的样式或者其他的时间,头像之类的设置,请按照自己的喜好实现,我只实现核心逻辑与功能,你若有更好的实现方法,请分享,谢谢!

Demo地址(here)

Github ~ https://github.com/LaravelChen/laravel-com...

1.利用Vuejs实现此功能的原由

我之前写过一个嵌套评论的Demo,是直接用Laravel5.4实现的,整个实现的过程也非常的清晰明了。项目说明在这里:

Laravel China:博客:Laravel 5~嵌套评论的实现

个人网站:https://laravelchen.com/article/36

在这之后,我的一个同学按照此步骤实现之后,想用 Vuejs实现,让整个评论没有刷新,用户体验更高!那么在实现的过程中,有很多地方使他无法实现这个功能,甚至想用Vuex来解决一些问题!so,我打算亲自试试用Vuejs来实现这个功能,顺便也为更多的遇到此类问题的朋友提供一个解决办法,Demo中的一些小问题,比如样式或者权限的设置交由你自己实现了,这里就不多阐述了!
接下来,直接开始看项目了!

2.准备工作

准备工作和之前利用Laravel5.4实现的嵌套评论基本一致,唯一要变化的是我们在Comment表增加一个字段level这个字段主要是来表示评论所属的层级数,若不设置这个level字段,则嵌套的层级数是无穷的,所以我最大设置为3,在下面的动态图中可以看到,当层级数为3的时候,则不再缩进显示了,这也是为了整个样式的美观考虑的。此外,为了让大家迅速的在本地实现Demo的效果,我简单的封装了命令,在终端下,执行以下命令:

php artisan createData

即可创建测试数据,最后放路由试试吧!祝你好运~哈哈!
使用npm安装:

npm install 
npm run dev

注意:
请在web.php中取消登录的注释,

\Auth::loginUsingId(1);

友情提醒:
如果你回复出现路由找不到,请在你的vue文件里面的axios.post使用你自己的域名,因为我使用的是valet开发,所以可以使用像linux一样的路径写法,但不代表可以在一些朋友的 windows环境下行的通! whatever!出现问题交给你自己解决了 。

3.实现想法

结合我的同学遇到的问题,我认为整个实现过程的难点在于怎么给创建来的json对象赋值,我们都知道,在vuejs中,父组件向子组件传值是行得通的,而子组件向父组件传值是不太好实现的,有可能你会想用vuex,或者利用$on$emit方法实现,但是作为开发者来说,用简单且有效的方法是首选,so,我只直接在子组件里面重新定义一个变量,让 props接受的值直接赋予给新创建的值,这样我将增加数据的操作直接放在新创建的值中,最后递归给下一个循环组件,这样就巧妙的实现了嵌套评论。
在这里还得着重讲一下我们后端整理的数据的结构,我是这样的:

public function getComments()
    {
        return $this->comments()->with('owner')->get()->groupBy('parent_id');
    }

其中groupBy是关键,我直接用parent_id作为分组标准,其中没有parent_id的直接赋予root,来表明是一个没有子评论的评论.
如下面:

$collections = $post->getComments();
$collections['root'] = $collections[''];
unset($collections['']);

这样一来,打印的数据的结构如下:

{
"1": [
     {
      "id": 2,
      "user_id": 3,
      "post_id": 1,
      "parent_id": 1,
      "body": "哈哈哈哈",
      "created_at": "2017-08-17 11:53:01",
      "updated_at": "2017-08-17 11:53:01",
      "level": 1,
      "owner": {
         "id": 3,
         "name": "Norwood Bogan",
         "email": "orion72@example.org",
         "created_at": "2017-08-17 23:59:41",
         "updated_at": "2017-08-17 23:59:41"
          }
    }
],
"root": [
    {
      "id": 1,
      "user_id": 2,
      "post_id": 1,
      "parent_id": null,
      "body": "这是一条评论\n",
      "created_at": "2017-08-17 10:58:00",
      "updated_at": "2017-08-17 10:58:00",
      "level": 0,
      "owner": {
          "id": 2,
          "name": "LaravelChen",
          "email": "848407695@qq.com",
          "created_at": "2017-08-17 14:48:40",
          "updated_at": "2017-08-17 14:48:40"
          }
    }
]
}

这样结构非常的清晰,我们只需要传入 root 这个数组给父组件即可,然后子组件按照相应的条件进行递归即可完成.那么具体的vue组件的代码请自行下载Demo进行查看.

4.效果图

image

如果对你有帮助可以点个赞哦 ☺!

本作品采用《CC 协议》,转载必须注明作者和本文链接
LaravelChen
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
讨论数量: 3
nff93

如果评论过多的时候,全部读取出来不合理,所以这个应该怎样分页呢?

一页10条评论,并把这10条评论的所有下级评论都给读出来

7年前 评论

@nff93 如果你要分页的话!给你个推荐个学习的demo!
https://github.com/JellyBool/laravel-vue-p...
原理都一样!

7年前 评论
nff93

@chenxin 这个demo不涉及无限级,所以并不能解决我说的那个问题啊~

比如:加载一篇文章后,读取parent_id === null的10条评论,然后需要加载这10条评论下的所有回复。

我目前想到的两种解决办法

  • 递归获取到所有这10条评论的回复
  • 在评论表增加一个reply字段,将当前评论的回复以json方式存入
7年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!