Laravel 5.3 + Vue Reddit式投票系统

时间:2016-09-28 12:58:54

标签: javascript php laravel vue.js

我正在学习Vuejs(首先不太精通Laravel),而我正试图在某些任务上制作一个简单的投票系统。我设法添加任务,编辑它们并删除它们,但是当我添加upvote / downvote时,投票数不会改变。

以下是routes\api.php中的Laravel路线:

Route::group(['middleware'=>'api'],function(){

Route::get('tasks', function(){
    return \App\Task::latest()->orderBy('created_at', 'desc')->get();
});

Route::get('task/{id}', function($id){
    return \App\Task::findOrFail($id);
});

Route::post('task/store', function(Request $request){
    return App\Task::create(['body' => $request->input(['body'])]);
});

Route::patch('task/{id}', function(Request $request, $id){
    return \App\Task::findOrFail($id)->update(['body' => $request->input(['body'])]);
});

Route::delete('task/{id}', function($id){
    return \App\Task::destroy($id);
});

Route::get('task/{id}/votes', function($id){
    return \App\Task::findOrFail($id)->votes->get();
});

Route::patch('task/{id}/votes', function(Request $request, $id){
    return \App\Task::findOrFail($id)->update(['votes'=> $request->input(['votes'])]);
}); 
});

Tasks表的迁移如下所示(我使用的是sqlite):

Schema::create('tasks', function (Blueprint $table) {
        $table->increments('id');
        $table->text('body');
        $table->integer('votes')->default(1);
        $table->timestamps();
    });

这是Vue的任务组件模板:

<h1>My Tasks</h1>
<hr>
<h4>New Task</h4>
<form action="#" @submit.prevent="edit ? updateTask(task.id) : createTask()">
    <div class="input-group">
        <input type="text" name="body" v-model="task.body" v-el:taskinput class="form-control" autofocus>
        <span class="input-group-btn">
            <button type="submit" class="btn btn-success" v-show="!edit">New Task</button>
            <button type="submit" class="btn btn-primary" v-show="edit">Edit Task</button>
        </span>
    </div>
</form>
<hr>
<hr>
<h3>All Tasks</h3>
<ul class="list-group">
    <li class="list-group-item" v-for="task in list">
        {{ task.body }}
        <button class="btn-success btn-xs" @click="upvote(task.id)" :class="{disabled: upvoted}">Upvote</button>
        <span class="label label-primary">{{ task.votes }}</span>
        <button class="btn-danger btn-xs" @click="downvote(task.id)" :class="{disabled: downvoted}">Downvote</button>
        <span class="pull-right">
            <button class="btn-primary btn-xs" @click="showTask(task.id)">Edit Task</button>
            <button class="btn-danger btn-xs" @click="deleteTask(task.id)">Delete Task</button>
        </span>
    </li>
</ul>

最后,Vue脚本:

export default{
    data(){
        return{
            edit: false,
            list: [],
            task: {
                id: '',
                body: '',
                votes: Number
            },
            upvoted: false,
            downvoted: false
        }
    },

    ready: function () {
        this.fetchTaskList();
    },

    methods:{

        fetchTaskList: function () {
            this.$http.get('api/tasks').then(function (response) {
                this.list = response.data
            });
        },

        createTask: function () {
            this.$http.post('api/task/store', this.task);
            this.task.body = '';
            this.edit = false;
            this.fetchTaskList();
        },

        updateTask: function (id) {
            this.$http.patch('api/task/' + id, this.task);
            this.task.body='';
            this.edit = false;
            this.fetchTaskList();
        },

        showTask: function (id) {
            this.$http.get('api/task/' + id).then(function (response) {
                this.task.id = response.data.id;
                this.task.body = response.data.body;
            });
            this.$els.taskinput.focus();
            this.edit = true;
        },

        deleteTask: function (id) {
            this.$http.delete('api/task/' + id);
            this.fetchTaskList();
        },

        updateVotes: function (id, votes) {
            this.$http.patch('api/task/'+id+'/votes', votes);
        },

        upvote: function (id) {
            this.$http.get('api/task/'+id+'/votes').then(function (response) {
                this.task.id = response.data.id;
                this.task.votes = response.data.votes + 1;
                updateVotes(this.task.id, this.task.votes);
            });
            this.upvoted = !this.upvoted;
            this.downvoted = false;
        },

        downvote: function (id) {
            this.$http.get('api/task/'+id+'/votes').then(function (response) {
                this.task.id = response.data.id;
                this.task.votes = response.data.votes - 1;
                updateVotes(this.task.id, this.task.votes);
            });
            this.upvoted = false;
            this.downvoted = !this.downvoted;
        },
    }
}

我猜这个错误是在Vue脚本的某个地方,要么我宣布投票错了(投票:数字?),要么我不能像我那样从upvote和downvote函数调用updateVotes函数。

编辑: 仍然没有工作,但我有Vue.js devtools,它肯定承认投票: https://snag.gy/sE5gp6.jpg

......但是以一种非常奇怪的方式。当我点击upvote时,devtools中的投票变为'11',而不是1.当我点击downvote时,它会回到0.但是在视图中它没有变化。这是在我改变之后的全部内容:

updateVotes(this.task.id, this.task.votes);

要:

this.updateVotes(this.task.id, this.task.votes);

..作为用户Dan建议,并在更改后:

upvote: function (id) {
        this.$http.get('api/task/'+id+'/votes')

要:

upvote: function (id) {
        this.$http.get('api/task/'+id)

因为我认为我之前只获得了投票,然后将它们视为其余功能的Task对象。同样适用于downvote函数。

这就是现在控制台中出现的内容:

  

vue-resource.common.js?d39b:966 PATCH http://localhost:8000/api/task/8/votes 500(内部服务器错误)(匿名函数)@ vue-resource.common.js?d39b:966Promise $ 1 @ vue-resource.common。 js?d39b:192xhrClient @ vue-resource.common.js?d39b:927sendRequest @ vue-resource.common.js?d39b:1060exec @ vue-resource.common.js?d39b:1017next @ vue-resource.common.js? d39b:1042before @ vue-resource.common.js?d39b:881exec @ vue-resource.common.js?d39b:1017next @ vue-resource.common.js?d39b:1042timeout @ vue-resource.common.js?d39b: 920exec @ vue-resource.common.js?d39b:1017next @ vue-resource.common.js?d39b:1042method @ vue-resource.common.js?d39b:895exec @ vue-resource.common.js?d39b:1017next @ vue-resource.common.js?d39b:1042body @ vue-resource.common.js?d39b:802exec @ vue-resource.common.js?d39b:1017next @ vue-resource.common.js?d39b:1042jsonp @ vue- resource.common.js?d39b:867exec @ vue-resource.common.js?d39b:1017next @ vue-resource.common.js?d39b:1042header @ vue-resource.common.js?d39b:903exec @ vue-resource。 common.js?d39b :1017next @ vue-resource.common.js?d39b:1042cors @ vue-resource.common.js?d39b:777exec @ vue-resource.common.js?d39b:1017next @ vue-resource.common.js?d39b:1042 (匿名函数)@ VM56:32exec @ vue-resource.common.js?d39b:1017(匿名函数)@ vue-resource.common.js?d39b:1045Promise $ 1 @ vue-resource.common.js?d39b:192Client @ vue-resource.common.js?d39b:1010Http @ vue-resource.common.js?d39b:1152Http。(匿名函数)@ vue-resource.common.js?d39b:1188updateVotes @ Tasks.vue?34c5:94(匿名函数)@ vue.common.js?4a36:216(匿名函数)@ Tasks.vue?34c5:102   localhost /:1未捕获(在承诺中)响应{url:“api / task / 8 / votes”,正文:“↵↵↵↵↵↵↵↵”,标题:对象,状态:500,statusText:“内部服务器错误“...}

2 个答案:

答案 0 :(得分:1)

如果你替换它是否有效:

updateVotes(this.task.id, this.task.votes);

使用

this.updateVotes(this.task.id, this.task.votes);

答案 1 :(得分:1)

(代表OP发布)

问题解决了。我没有在任务模型中添加protected $fillable = ['votes']