Laravel Vuejs 实战:开发知乎 (6)发布问题
1.view部分:
安装一个扩展包:Laravel-UEditor
1 composer require "overtrue/laravel-ueditor:~1.0"
配置
添加下面一行到 config/app.php 中 providers 部分:
1 Overtrue\LaravelUEditor\UEditorServiceProvider::class,
1 php artisan vendor:publish --provider=”Overtrue\LaravelUEditor\UEditorServiceProvider”
这行的作用是引入编辑器需要的 css,js 等文件,所以你不需要再手动去引入它们。
1 @include('vendor.ueditor.assets')
1 <!-- 实例化编辑器 --> 2 <script type="text/javascript"> 3 var ue = UE.getEditor('container'); 4 ue.ready(function() { 5 ue.execCommand('serverparam', '_token', '{{ csrf_token() }}'); // 设置 CSRF token. 6 }); 7 </script> 8 9 <!-- 编辑器容器 --> 10 <script id="container" name="content" type="text/plain"></script> 11
5.4+ 请不要忘记 php artisan storage:link
如果你使用的是 laravel 5.3 以下版本,请先创建软链接:
# 请在项目根目录执行以下命令
$ ln -s `pwd`/storage/app/public `pwd`/public/storage
在 config/ueditor.php 配置 disk 为 'public' 情况下,上传路径在:public/uploads/ 下,确认该目录存在并可写。
如果要修改上传路径,请在 config/ueditor.php 里各种类型的上传路径,但是都在 public 下。
请在 .env 中正确配置 APP_URL 为你的当前域名,否则可能上传成功了,但是无法正确显示。
更多请参考 Laravel-UEditor
在views文件夹下新建一个questions文件夹,并在该子文件夹内新建一个create.blade.php文件,代码如下:
1 @extends('layouts.app') 2 @section('content') 3 @include('vendor.ueditor.assets') 4 <div class="container"> 5 <div class="row"> 6 <div class="col-md-8 col-md-offset-2"> 7 <div class="panel panel-default"> 8 <div class="panel-heading"> 9 发布问题 10 </div> 11 <!-- 编辑器容器 --> 12 <script id="container" name="content" type="text/plain"></script> 13 </div> 14 </div> 15 </div> 16 </div> 17 18 <!-- 实例化编辑器 --> 19 <script type="text/javascript"> 20 var ue = UE.getEditor('container'); 21 ue.ready(function () { 22 ue.execCommand('serverparam', '_token', '{{ csrf_token() }}'); // 设置 CSRF token. 23 }); 24 </script> 25 26 @endsection 27
注意可以在上一节 Laravel Vuejs 实战:开发知乎 (5)设计问题表 中提到的命令改成使用
1 1 php artisan make:model Models/Question -cmr
这样直接就采用了RESTFul式的Controller,比较方便;web.php中也可以直接:
1 Route::resource(‘questions’,’QuestionController’);
如果已经执行过了,可以删除QuestionController然后执行:
1 php artisan make:controller QuestionController –r 2 3 或 4 5 php artisan make:controller QuestionController –resource
在web.php 文件中添加一个:
1 Route::resource('questions', 'QuestionController');
当访问 http://zhihu.test/questions/create 链接的时候会 由QuestionController中的create方法来接待,我们需要返回一个view【视图界面】,所以修改添加如下代码:
1 /** 2 * Show the form for creating a new resource. 3 * 4 * @return \Illuminate\Http\Response 5 */ 6 public function create() 7 { 8 //返回questions文件夹下create.blade.php作为视图 9 return view('questions.create'); 10 } 11
结果如下:
正确显示视图,但是我们是需要发布问题,这里只是看到了编辑器,所以我们修改create.blade.php视图代码如下:
注:如果忘记了或者不太清楚questions提交保存的route路由别名,可以用命令行: php artisan route:list ,会列出所有的route路由信息,如图:
1 @extends('layouts.app') 2 @section('content') 3 @include('vendor.ueditor.assets') 4 <div class="container"> 5 <div class="row"> 6 <div class="col-md-8 col-md-offset-2"> 7 <div class="card"> 8 <div class="card-header"> 9 发布问题 10 </div> 11 <div class="card-body"> 12 <form action="{{ route('questions.store') }}" method="post"> 13 {{--注意要有csrftoken--}} 14 @csrf 15 <div class="form-group"> 16 <label for="title">标题</label> 17 <input type="text" name="title" class="form-control" placeholder="标题" id="title"> 18 <p class="text text-danger"> @error('title') {{ $message }} @enderror </p> 19 </div> 20 <!-- 编辑器容器 --> 21 <script id="container" name="content" type="text/plain"></script> 22 <p class="text text-danger"> @error('content') {{ $message }} @enderror </p> 23 <!--发布按钮--> 24 <button type="submit" class="btn btn-primary mt-2 float-md-right">发布问题</button> 25 </form> 26 </div> 27 </div> 28 </div> 29 </div> 30 </div> 31 32 <!-- 实例化编辑器 --> 33 <script type="text/javascript"> 34 var ue = UE.getEditor('container'); 35 ue.ready(function () { 36 ue.execCommand('serverparam', '_token', '{{ csrf_token() }}'); // 设置 CSRF token. 37 }); 38 </script> 39 40 @endsection 41
效果如图:
注意:为了上传图片可以读写,请事前执行一下命令:
1 php artisan storage:link
图片上传的具体配置上传大小,格式,位置都是由config/ueditor.php中 ‘upload’列里保存配置信息来具体设置的
由于提交后的数据是由QuestionController中的store方法来处理的,先测试提交一个数据用 dd()方法查看数据:
所以现在来编辑store方法,代码如下:
1 public function store(Request $request) 2 { 3 // 4 $data = $request->validate([ 5 'title' => 'required|min:8', 6 'content' => 'required|min:8', 7 ]); 8 9 $data['user_id'] = auth()->user()->id; 10 11 $question = Question::create($data); 12 13 return redirect()->route('questions.show', $question); 14 }
由于上一节中问题数据库迁移设计的时候,忘记了user_id字段,所以添加一下,具体方法参考:Laravel 6.X 数据库迁移 创建表 与 修改表
执行:
其中代码1 php artisan make:migration add_user_id_to_questions_table --table=questions
然后执行:
1 php artisan migrate
记得添加Question模型中的 属性值
1 protected $fillable = ['title', 'content', 'user_id']; //否则会提示MassAssignmentException ,也可以使用guard属性 具体看官方文档
store方法中,保存了数据之后,就跳转至show route,会由QuestionController的show方法来处理请求,我们先测试一下 提交问题之后,结果如图:
修改show方法中的代码如下:
1 /** 2 * Display the specified resource. 3 * 4 * @param Question $question 5 * @return \Illuminate\Http\Response 6 */ 7 public function show(Question $question) 8 { 9 // 10 return view('questions.show', compact('question')); 11 } 12
接下来,在views/questions文件夹下创建一个show.blade.php文件:其中代码如下:
1 @extends('layouts.app') 2 3 @section('content') 4 5 <div class="container"> 6 <div class="row"> 7 <div class="col-md-8 col-md offset-2"> 8 <div class="card"> 9 <div class="card-header"> 10 {{ $question->title }} 11 </div> 12 <div class="card-body"> 13 {!! $question->content !!} 14 </div> 15 </div> 16 </div> 17 </div> 18 </div> 19 20 @endsection 21