Laravel 5.3 + Vue 类似 Reddit 的投票系统
Posted
技术标签:
【中文标题】Laravel 5.3 + Vue 类似 Reddit 的投票系统【英文标题】:Laravel 5.3 + Vue Reddit-like voting system 【发布时间】:2017-02-06 11:31:42 【问题描述】:我正在学习 Vuejs(首先对 Laravel 不太精通),并且我正在尝试为某些任务制作一个简单的投票系统。我设法添加、编辑和删除任务,但是当我添加赞成/反对的内容时,投票数没有改变。
所以这里是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 的 Tasks 组件模板:
<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 开发工具,它肯定会识别选票: 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)
因为我认为我以前只是获得选票,然后将它们视为任务对象,用于函数的其余部分。 downvote 函数也是如此。
这就是现在控制台中出现的内容:
vue-resource.common.js?d39b:966 PATCH http://localhost:8000/api/task/8/votes 500 (Internal Server Error)(匿名函数) @ 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。 j s?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 Uncaught (in promise) 响应 url: "api/task/8/votes", body: "↵↵ ↵ ↵↵↵ ↵ ↵", headers: Object, status: 500, statusText: "Internal Server Error “……
【问题讨论】:
【参考方案1】:如果你替换它是否有效:
updateVotes(this.task.id, this.task.votes);
有
this.updateVotes(this.task.id, this.task.votes);
【讨论】:
仍然没有,但我想这是需要改变的事情之一。 您的浏览器控制台或日志文件中是否有任何错误? 加载资源失败:服务器响应状态为 500 (Internal Server Error) localhost:8000/api/task/7/votes Uncaught (in promise) 响应。但是,在您发表第一条评论后,我注意到我在获得选票的路线上犯了一个错误。我这样做了: Route::get('task/id/votes', function($id) return \App\Task::findOrFail($id)->votes->get(); );但将其视为 vue 脚本中的 Task 对象。所以我将 Vue 的 upvote 和 downvote 函数更改为: this.$http.get('api/task/'+id) 而不是 this.$http.get('api/task/'+id +'/votes ') 在 Chrome 开发者工具中,点击网络标签。您应该会看到一个 AJAX 请求列表,因为它们正在生成。单击导致问题的请求,然后单击另一个窗口中的响应或预览选项卡。这可能会让您更好地了解正在发生的事情。如果没有,请尝试查看您的 Laravel 日志文件(通常是 storage/logs/laravel-todaysdate.log) 好的,非常感谢。我一回到家就会这样做。【参考方案2】:(代表 OP 发布).
问题解决了。我没有在 Task 模型中添加protected $fillable = ['votes']
。
【讨论】:
以上是关于Laravel 5.3 + Vue 类似 Reddit 的投票系统的主要内容,如果未能解决你的问题,请参考以下文章