【问题标题】:Laravel 5: show comments using Vue.jsLaravel 5:使用 Vue.js 显示评论
【发布时间】:2020-02-01 09:51:53
【问题描述】:

我正在创建博客评论系统,我想为使用 vue.js 的帖子显示 cmets。 在控制台中,它说

属性或方法“注释”未在实例上定义,但 在渲染期间引用。

另外,当我尝试捕获用户名时,我得到了这个错误

渲染错误:“TypeError:无法读取未定义的属性‘用户’”

我想显示对特定帖子发表评论的 cmets 和用户

在 show.blade.php 中。

web.php

Route::get('results/{post}', 'ResultsController@show')->name('posts.show');

结果控制器

public function show(Post $post)
{
    $recommended_posts = Post::latest()
                        ->whereDate('date','>',date('Y-m-d'))
                        ->where('category_id','=',$post->category_id)
                        ->where('id','!=',$post->id)
                        ->limit(7)
                        ->get();

    $posts['particular_post'] = $post;
    $posts['recommended_posts'] = $recommended_posts;

    //return $post->comments()->paginate(5);  it returns objects

    return view('posts.show',compact('posts'));
}

评论.vue

<div class="reply-comment" :v-for="comment in comments">
                 <div class="user-comment" >
                    <div class="user">
                        <!--<img src="" alt="" >-->
                        <avatar :username="comment.user.name" :size="30" ></avatar>
                    </div>
                    <div class="user-name">
                        <span class="comment-name">{{ comment.user.name }}</span>
                        <p> {{ comment.body }} </p>
                    </div>
                </div>
                <div class="reply">
                    <div class="seemorecomments">
                        <a href="">see more</a>
                    </div>
                    <button class="reply-button">
                        <i class="fas fa-reply"></i>
                    </button>
                </div>
            </div>


<script>
import Avatar from 'vue-avatar'
export default {
    props: ['post'],
    components: {
        Avatar
    },
    mounted() {
        this.fetchComments()
    },
    data: () => ({
        comments: {
            data: []
        }
    }),
    methods: {
        fetchComments() {
            axios.get(`/results/${this.post.id}`).then(({ data }) => {
                this.comments = data
            })
        }
    }
}

show.blade.php

<comments-component :post="{{ $posts['particular_post']->comments }}"></comments-component>

迁移表

Schema::create('comments', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->integer('user_id');
        $table->integer('post_id');
        $table->text('body');
        $table->integer('comment_id')->nullable();
        $table->timestamps();
    });

comment.php,我有这个。

protected $with = ['user'];

【问题讨论】:

  • 您是否尝试过检查 ResultsController@show 是否返回所需的数据?
  • 我做了,我把 return $post->cmets()->paginate(5);在控制器中,我可以看到 5 个对象。
  • console.log 在您的 api 回调中记录 data 对象并检查 data 对象。我认为应该是 this.cmets = data.data。 (首先检查您的数据对象)
  • 您使用相同的端点来显示视图并获取 cmets。因此,当调用 fetchComment() 方法时,您的 ResultsController@show 不会返回 JSON,而是返回包含您的视图的 HTML。尝试创建一个专用端点,以 JSON 格式返回某个帖子的 cmets。
  • @JulioMotol 我添加了一个新端点 Route::get('results/{post}/cmets', 'CommentsController@index');并像这样(/results/${this.post.id}/comments)进行了更改,但没有成功。

标签: javascript php laravel vue.js fetch


【解决方案1】:

您的 Vue 文件有几个小问题,可以很快解决。

首先,您应该将comments 定义为一个空数组——一个集合将作为一个对象数组返回给 Vue。通过在开头添加一个不必要的data 属性,您可以在检索数据之前允许v-for 循环在您的模板中运行。

编辑:我不确定你写这个数据函数的方式,所以我用我熟悉的方式重写了它。

data() {
    return {
        comments: []
    }
},

其次,您想从响应中获取正确的数据。 Axios 数据存储在另一层深 (response.data)。当然,如果您对结果进行分页,它们会更深一层 (response.data.data)。

fetchComments() {
    axios.get(`/results/${this.post.id}`).then(response => {
        this.comments = response.data

        // or for paginated results
        // this.comments = response.data.data
    })
}

编辑:感谢您提供要点!我想我现在看得更清楚了。

像这样更新您的控制器:
您想在此处将 cmets 加载到帖子中。

public function show(Post $post)
{
    $recommended_posts = Post::latest()
                        ->whereDate('date','>',date('Y-m-d'))
                        ->where('category_id','=',$post->category_id)
                        ->where('id','!=',$post->id)
                        ->limit(7)
                        ->get();

    // load the post comments here
    $post->load('comments');
    $posts['particular_post'] = $post;
    $posts['recommended_posts'] = $recommended_posts;

    return view('posts.show',compact('posts'));
}

你的刀片是这样的:
你的模块需要一个帖子,而不是一个 cmets 数组。

<comments-component :post="{{ $posts['particular_post'] }}"></comments-component>

而你的 Vue 是这样的:
你实际上根本不需要使用 Axios,因为我们已经加载了 cmets。

<script>
    import Avatar from 'vue-avatar'
    export default {
        props: ['post'],
        components: {
            Avatar
        },
        data() {
            return {
                comments: this.post.comments
            }
        },      
    }
</script>

【讨论】:

  • 谢谢,但我仍然有同样的错误。 “评论”未在实例上定义”。
  • 我已经把 $post->cmets()->with('user')->get();在 ResultsController 但我仍然有同样的错误。无法读取未定义的属性“用户”。
  • 我看到您新添加了protected $with = ['user'],它应该会处理这种关系。你确定你所有的 cmets 都分配给了一个用户吗?您能否将更新后的代码发布到 Gist,包括 Comment.php 模型?
  • 感谢您回答我。我上传了我的代码,如果您需要更多,请随时询问。 gist.github.com/YoheiUmezu/6583a87933ed94ff7df28eb532819632
  • 我也试过添加一个新的端点。如果您检查stackoverflow.com/questions/58217427/…,我很高兴。
猜你喜欢
  • 2020-01-31
  • 1970-01-01
  • 2018-12-15
  • 2015-07-13
  • 2020-08-29
  • 2011-10-02
  • 2016-07-06
  • 2021-05-14
  • 1970-01-01
相关资源
最近更新 更多