我已经寻找了相当长的一段时间,但没有找到什么方便的东西。
在Laravel中实现Vue MPA架构的最佳方法和实践是什么。
已经搜索了很久,但没有找到任何清晰的想法。您的答案将会非常有帮助,请尽量简要回答。
回答以下问题也将有所帮助:
- 仅使用laravel作为数据API,并将Vue与laravel分开是否是个好主意?
- 实现SPA和MPA混合的最佳方法。
我已经寻找了相当长的一段时间,但没有找到什么方便的东西。
在Laravel中实现Vue MPA架构的最佳方法和实践是什么。
已经搜索了很久,但没有找到任何清晰的想法。您的答案将会非常有帮助,请尽量简要回答。
回答以下问题也将有所帮助:
我已经尝试过的一些选项:
基本上,Laravel 将呈现 Vue 应用程序,并且每个请求都经过 API。
这可能需要更多时间,因为您需要设置额外的服务器、准备跨域等。
您可以使用 Laravel 渲染所有视图 + vuejs 用于页面中的组件/元素。
--
所有选项都可测试和扩展。
这也取决于您如何开始(我应该担心将来如何分离应用程序吗?Laravel + Vue是否长期使用?),您的团队将如何工作(前端团队真的需要设置Laravel还是他们只需要关注前端代码?)等等。
如果我没有回答您的问题,请留下评论。
你还没有找到明确的答案,因为除了“符合你的理解和项目需求”的内容之外,真的没有什么可谈的了。如果你发现自己非常不确定,可以随意尝试做任何有意义的事情,然后在获得更多经验后重新调整结构。
此外,阅读关于系统架构的书籍会很有帮助。
实现SPA和MPA混合的最佳方法。
根据我的经验,我曾尝试构建4个以上的混合项目,以下是我发现的最优结构:
我的示例将涉及一个保存“帖子”的应用程序。
这将在维护代码和保持DRY(不要重复自己)概念方面为您节省很多麻烦。
App\Repositories\
创建一个新类PostsRepository
。这将是与数据库通信并包含大部分逻辑的类。
App\Services\
创建一个新类PostsService
。这将在其构造函数中具有PostsRepository
。
服务类将处理用户的输入,无论是来自Web控制器还是API控制器。
<?php
namespace App\Service;
use App\Repositories\PostsRepository;
class PostsService;
{
protected $repository;
public function __construct(PostsRepository $repository)
{
$this->repository = $repository;
}
}
对于Web控制器,您可以像往常一样创建控制器:
php artisan make:controller PostsController
对于API控制器,您需要将控制器创建在Api文件夹中。
php artisan make:controller Api\PostsController
最后一个命令将创建目录App\Http\Controllers\Api并将控制器放置其中。
回顾
现在我们有了不同的控制器,以返回适合起点(Web / API)的结果。
我们有服务,这些(Web / API)控制器都将其数据发送以进行验证(并由存储库执行操作)。
例如:
<?php
namespace App\Http\Controllers;
use App\Service\PostsService;
class PostsController extends Controller
{
protected $service;
public function __construct(PostsService $service)
{
$this->service = $service;
}
public function index()
{
/**
* Instead of returning a Blade view and
* sending the data to it like:
*
* $posts = $this->service->all();
* return views('posts.index', compact('posts'));
*
* We go ahead and just return the boilerplate of
* our posts page (Blade).
*/
return view('posts.index');
}
}
...
<?php
namespace App\Http\Controllers\Api;
use App\Service\PostsService;
class PostsController extends Controller
{
protected $service;
public function __construct(PostsService $service)
{
$this->service = $service;
}
/**
* Returns all posts.
*
* A vue component calls this action via a route.
*/
public function index()
{
$posts = $this->service->all();
return $posts;
}
/**
* Notice we don't have a store() in our
* Web controller.
*/
public function store()
{
return $this->service->store();
}
}
...
<?php
namespace App\Services;
use App\Repositories\PostsRepository;
class PostsService extends Controller
{
protected $repository;
public function __construct(PostsRepository $repository)
{
$this->repository = $repository;
}
public function all()
{
$posts = $this->repository->all();
return $posts;
}
public function store()
{
$request = request()->except('_token');
$this->validation($request)->validate();
return $this->repository->store($request);
}
public function validation(array $data)
{
return Validator::make($data, [
'content' => 'required|string|max:255',
//
]);
}
}
在我们的PostsRepository中,实际上调用保存数据的方法。例如:Post::insert($request);
。
Route::prefix('api/v1')->middleware('auth')->group(function() {
Route::post('posts/store', 'Api\PostsController@store')->name('api.posts.store');
});
给API路由加上->name()
在进行phpunit测试时非常有帮助。
这些应该是简化的简单视图。
views/posts/index.blade.php
:
@extends('layouts.app', ['title' => trans('words.posts')])
@section('content')
<!-- Your usual grid columns and stuff -->
<div class="columns">
<div class="column is-6">
<!-- This comp. can have a modal included. -->
<new-post-button></new-post-button>
<div class="column is-6">
<posts-index-page></posts-index-page>
</div>
</div>
@endsection
https://github.com/pablohpsilva/vuejs-component-style-guide
那么这些Vue组件可能会存储在resources/assets/js/components/posts/
中,其中/posts/
内部会有文件夹,例如IndexPage
、CreateModal
和EditModal
,每个文件夹都有其自己的.vue
和README.md
。index.blade.php
中使用<posts-index-page>
,并在需要时放置<post-create-modal>
和<edit-post-modal>
。README.md
是用来做什么的? - common sense<edit-post-page>
比较简单,那么是的,我会传递一个:post_id
属性。但是,在更复杂的情况下,如果多个组件都需要:post_id
,我更喜欢使用Vuex来管理我的状态,这样我可以在任何组件中访问我的状态的post_id
而无需传递props。 - Shafiq al-Shaar