小编给大家分享一下基于Laravel+Vue组件实现文章发布、编辑和浏览功能的示例,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!
创新互联成立于2013年,是专业互联网技术服务公司,拥有项目成都做网站、成都网站制作、成都外贸网站建设网站策划,项目实施与项目整合能力。我们以让每一个梦想脱颖而出为使命,1280元龙马潭做网站,已为上家服务,为龙马潭各地企业和个人服务,联系电话:18982081108
我们将基于 Laravel 提供后端接口,基于 Vue.js 作为前端 JavaScript 组件开发框架,基于 Bootstrap 作为 CSS 框架。
Laravel 后端接口
首先,我们基于上篇教程创建的资源控制器 PostController 快速编写后端增删改查接口实现代码:
middleware('auth')->except('index', 'all', 'show', 'data');
    }
    /**
     * Display a listing of the resource.
     *
     * @return Application|Factory|View|Response|\Illuminate\View\View
     */
    public function index()
    {
        return view('posts.index', ['pageTitle' => '文章列表页']);
    }
    /**
     * Show the form for creating a new resource.
     *
     * @return Application|Factory|View|Response|\Illuminate\View\View
     */
    public function create()
    {
        return view('posts.create', ['pageTitle' => '发布新文章']);
    }
    /**
     * Store a newly created resource in storage.
     *
     * @param Request $request
     * @return array
     */
    public function store(Request $request)
    {
        $data = $request->validate([
            'title' => 'required|max:128',
            'content' => 'required'
        ]);
        $post = new Post($data);
        $post->status = 1;
        $post->user_id = Auth::user()->id;
        if ($post->save()) {
            return ['success' => true, 'message' => '文章发布成功'];
        }
        return ['success' => false, 'message' => '保存文章数据失败'];
    }
    /**
     * Display the specified resource.
     *
     * @param Post $post
     * @return Application|Factory|View|Response|\Illuminate\View\View
     */
    public function show(Post $post)
    {
        return view('posts.show', ['id' => $post->id, 'pageTitle' => $post->title]);
    }
    /**
     * Show the form for editing the specified resource.
     *
     * @param Post $post
     * @return Application|Factory|View|Response|\Illuminate\View\View
     */
    public function edit(Post $post)
    {
        return view('posts.edit', ['pageTitle' => '编辑文章', 'id' => $post->id]);
    }
    /**
     * Update the specified resource in storage.
     *
     * @param Request $request
     * @param Post $post
     * @return array
     */
    public function update(Request $request, Post $post)
    {
        $data = $request->validate([
            'title' => 'required|max:128',
            'content' => 'required'
        ]);
        $post->fill($data);
        $post->status = 1;
        if ($post->save()) {
            return ['success' => true, 'message' => '文章更新成功'];
        }
        return ['success' => false, 'message' => '更新文章数据失败!'];
    }
    /**
     * Remove the specified resource from storage.
     *
     * @param Post $post
     * @return array
     * @throws Exception
     */
    public function destroy(Post $post)
    {
        if ($post->delete()) {
            return ['success' => true, 'message' => '文章删除成功'];
        }
        return ['success' => false, 'message' => '删除文章失败'];
    }
    /**
     * 获取所有文章数据
     *
     * @return Collection
     */
    public function all()
    {
        return Post::orderByDesc('created_at')->get();
    }
    /**
     * 获取单个文章数据
     *
     * @param Post $post
     * @return Post
     */
    public function data(Post $post)
    {
        $post->author_name = $post->author->name;
        return $post;
    }
}除了 Laravel 资源控制器自带的方法之外,我们额外提供了 all 和 data 两个方法,分别用于在 Vue 组件中通过 AJAX 请求获取文章列表数据和文章详情数据。因此,需要在路由文件 routes/web.php 中注册资源路由之前添加这两个方法对应的路由:
use App\Http\Controllers\PostController;
Route::get('posts/all', [PostController::class, 'all']);
Route::get('posts/{post}/data', [PostController::class, 'data']);
Route::resource('posts', PostController::class);注意这里我们使用了 Laravel 路由提供的隐式模型绑定功能快速获取模型实例。此外,相应的视图模板路径也做了调整,我们马上会介绍这些视图模板文件。
通过填充器填充测试数据
如果你在上篇教程填充的测试数据基础上新增过其他数据,可以运行 php artisan migrate:refresh 命令重建数据表快速清空已有数据并重新填充。
如果你不想查看返回实例数据格式的细节,可以在自带填充器 database/seeders/DatabaseSeeder.php 中定义填充代码:
create(); Post::factory(10)->create(); } }
然后运行  php artisan migrate:refresh --seed 命令即可一步到位完成数据表重建、测试数据清空和重新填充:
cdn.xueyuanjun.com/storage/uploads/images/gallery/2020-10/16036945542122.jpg">

通过模板继承重构视图模板
由于我们使用的是 Laravel 提供的 laravel/ui 扩展包提供的 Bootstrap 和 Vue 前端脚手架代码,该扩展包还提供了用户认证相关脚手架代码实现,并且提供了一个视图模板布局文件 resources/views/layouts/app.blade.php,我们将通过模板继承基于这个布局文件来重构文章列表、表单、详情页相关视图模板文件,让整体 UI 统一。
不同页面设置不同标题
我们前面在 PostController 中,为所有 GET 路由渲染的视图文件传递了 pageTitle  值作为不同页面的标题,要实现该功能,需要修改 resources/views/layouts/app.blade.php 布局文件中 title 标签对应的标签文本值:
{{ $pageTitle ?? config('app.name', 'Laravel') }} 
文章列表视图
接下来,将原来的文章相关视图文件都移动到 resources/views/posts 目录下,改写文章列表视图文件模板代码如下(将原来的 posts.blade.php 重命名为 index.blade.php):
@extends('layouts.app')
@section('content')
    
        
@endsection文章发布视图
将原来的 form.blade.php 重命名为 create.blade.php,并编写文章发布表单页面视图文件模板代码如下:
@extends('layouts.app')
@section('content')
    
        
            
             
        
    
@endsection由于文章发布和编辑表单共用一个 Vue 表单组件,所以我们这里额外传递了一些 props 属性到组件模板,包括表单标题(title)、操作类型(action)、表单提交 URL(url),后面马上会介绍表单组件的调整。
文章编辑视图
在 resources/views/posts 目录下新建一个 edit.blade.php 作为文件编辑页面视图文件,并编写模板代码如下:
@extends('layouts.app')
@section('content')
    
        
             $id]) }}">
             
        
    
@endsection同样也使用 post-form 模板渲染文章编辑表单,只不过额外传递了一个 id 属性,用于在表单组件初始化待编辑的文章数据。
文章详情页视图后面单独介绍。
重构 Vue 表单组件代码
为了适配文章编辑表单,以及后端接口返回数据格式的调整,我们需要修改 Vue 表单组件实现代码:
{{ title }} 
{{ form.message }} 
文章发布和编辑页面需要通过标题予以区分,所以我们通过 title 属性从父级作用域传递该标题值。
对于文章编辑表单,首先,我们会根据父级作用域传递的 id 属性值在 mounted 钩子函数中调用新增的 load 方法从后端接口 /posts/{post}/data 加载对应文章数据填充表单。
现在后端接口可以自动获取当前认证用户的 ID,所以 author 字段就没有必要填写了,直接将其移除。
文章创建和编辑对应的请求方式是不一样的,操作成功后处理逻辑也是不一样的(前者重定向到列表页,后者重定向到详情页),所以根据 action 属性值分别进行了处理。
此外,由于后端对表单数据进行验证后,保存数据阶段依然可能失败,所以前端提交表单后返回的响应状态码为 200 并不表示表单提交处理成功,还需要借助响应实体(JSON 格式)中的 success 字段进一步判断,进而通过 ToastMsg 子组件渲染成功或失败的提示文本。
ToastMsg 是从之前的 SuccessMsg 组件升级而来,直接将 SuccessMsg 组件重命名为 ToastMsg 并改写组件代码如下:
可以看到,如果表单提交处理成功(依然基于父级作用域传递的 form.success 属性)则显示成功提示样式及文案,否则显示失败提示样式和文案,而是否渲染该组件取决于表单验证是否成功,该字段基于父级作用域传递的 form.validated 属性,之前是没有这个属性的,所以我们需要额外添加,在 resources/js/form.js 中,调整相关代码实现如下:
class Form {
    constructor(data) {
        ...
        this.validated = false;
    }
    ...
    
    /**
     * 表单提交处理
     *
     * @param {string} url
     * @param {string} method
     */
    submit(url, method) {
        return new Promise((resolve, reject) => {
            axios[method](url, this.data())
                .then(response => {
                    this.onSuccess(response.data);
                    this.validated = true;
                    if (this.success === true) {
                        resolve(response.data);
                    } else {
                        reject(response.data);
                    }
                })
                .catch(error => {
                    this.onFail(error.response.data.errors);
                    reject(error.response.data);
                });
        });
    }
    /**
     * 处理表单提交成功
     *
     * @param {object} data
     */
    onSuccess(data) {
        this.success = data.success;
        this.message = data.message;
        this.reset();
    }
    
    ...
}这样一来,文章发布和编辑共用的 Vue 表单组件就重构好了。
文章详情页视图和 Vue 组件实现
我们接着来实现文章详情页。
PostDetail 组件
在 component-practice/resources/js/components 目录下新建一个 PostDetail.vue 文件作为渲染文章详情的 Vue 单文件组件,并编写组件代码如下:
Loading...
{{ title }}
Created at {{ created_at | diff_for_human }} by {{ author_name }}, Status: {{ status | post_status_readable }}, Action: 编辑
{{ content }}
这个组件功能比较简单,在 mounted 钩子函数中通过父级作用域传递的 id 属性值调用 load 函数加载后端接口返回的文章数据,并通过数据绑定将其渲染到模板代码中,在加载过程中,会有一个动态的加载状态提示用户文章数据正在加载。
这里我们还使用了过滤器对数据进行格式化,日期过滤器已经是全局的了,状态过滤器之前是本地的,这里我们将其从文章列表卡片组件 CardItem 中将其迁移到 app.js 中作为全局过滤器:
Vue.filter('post_status_readable', status => {
    switch(status) {
        case 0:
            return '草稿';
        case 1:
            return '已发布';
        default:
            return '未知状态';
    }
});然后就可以在任何 Vue 组件中调用它了(CardItem 中过滤器调用代码做一下相应调整)。
在 app.js 中注册这个组件:
Vue.component('post-detail', require('./components/PostDetail.vue').default);文章详情页视图文件
再到 component-practice/resources/views/posts 目录下新建 show.blade.php 视图文件引用 post-detail 组件即可:
@extends('layouts.app')
@section('content')
    
@endsection优化文章列表组件
最后,我们到文章列表组件中新增一个发布文章入口。
打开子组件 ListSection,在视图模式切换按钮右侧新增一个插槽,用于从父级作用域传递更多额外操作按钮:
...
然后在 PostList 中将发布文章按钮放到这个插槽中(样式代码也做了微调):
文章列表 新文章 {{ post.title }} ...
顺便也为文章列表所有文章设置详情页链接,ListItem 链接是从 PostList 通过 props 属性传递的,CardItem 需要去子组件中设置:
至此,我们就完成了文章列表、发布、编辑和详情页的所有前后端功能代码编写。
整体测试
如果你已经在本地运行了 npm run watch 并且通过 php arstisan serve 启动 PHP 内置 Web 服务器的话,就可以在浏览器通过 http://127.0.0.1:3002/posts (启用了 BrowserSync 代理)访问新的文章列表页了:

点击任意文章链接,即可进入文章详情页,加载数据成功之前,会有如下动态加载效果:


你可以点击「编辑」链接对这篇文章进行编辑:

更新成功后,会跳转到文章详情页,对应字段均已更新,并且状态也从草稿变成了已发布:

当然,文章发布和编辑功能需要用户处于已登录状态(目前未做权限验证),如果未登录的话,点击编辑和新文章按钮会先跳转到登录页面(该功能由 PostController 控制器构造函数中定义的中间件方法实现),我们在已登录情况下在文章列表页点击右上角的「新文章」按钮进入文章发布页面:

发布成功后,页面会跳转到文章列表页,并在列表中出现刚刚创建的文章:

增删改查还剩下一个「删」,下篇教程,就来给大家演示文章删除功能实现,为什么单独介绍呢,因为我想结合删除功能演示基于 Vue 组件的模态框、对话框以及过渡效果的实现。
看完了这篇文章,相信你对“基于Laravel+Vue组件实现文章发布、编辑和浏览功能的示例”有了一定的了解,如果想了解更多相关知识,欢迎关注创新互联行业资讯频道,感谢各位的阅读!
当前名称:基于Laravel+Vue组件实现文章发布、编辑和浏览功能的示例
本文链接:http://www.scyingshan.cn/article/jjcggc.html

 建站
建站
 咨询
咨询 售后
售后
 建站咨询
建站咨询 
 