Vue.js: the best way to implement MPA (multi-page application) in laravel

I looked around for a long time, but did not collect anything.

What will be the best approach and practice for implementing the Vue MPA architecture in laravel.

I searched quite a lot. But there is nothing that will give you a clear idea. Your answer will help a lot, please make it concise.

It will also be useful to answer this question:

  • Is it a good idea to use only laravel as the data API, and keep Vue separate from laravel?
  • The best approach for implementing SPA and MPA hybrids.
+5
source share
2 answers

Some options that I have already used:

Use Laravel to render the "main view" + connect the vue.js. application

Basically laravel will display the Vue application, and each request goes through an API.

  • Easy setup
  • Authentication + user verification is easier (for this you can use the laravel session manager - no need to create / use tokens or anything else. "No need to worry about the state of your application.")
  • It's easy to “disconnect” from Laravel - if in the future you want to separate the SPA application.

Use laravel (or clearance) only as an API, and on another server - SPA.

This may take longer since you need to configure an additional server, prepare cross-start, etc.

  • Also easy to set up, but may take longer than option # 1
  • You need to create something to check / manage users, etc.
  • Easy to host in laravel if you decide to use "only one application" in the future.
  • It may be easier to maintain / scale (if you have a frontman command, they don’t need to worry about laravel - the same goes for your “laravel command”, they don’t need to worry about the interface)

Laravel + Vue = "one application"

You can use Laravel to display all + vuejs views for components / elements on the page.

  • Easy setup. You have laravel + vuejs and they are ready for sharing. https://laravel.com/docs/5.5/frontend#writing-vue-components
  • Not so easy to separate. In this case, you will need to create the same views for vue.js. This may take some time.
  • This is "traditional web development" (in my opinion). If I had to start such a project today, I would not have created all the pages in Vue.js + something in Laravel (Controller + new route) to display this view. If you do this (again, my opinion), this is just extra work. If you are worried about SEO, there are “backup” / advanced options.

-

All parameters can be tested + scaled.

It also depends on how you start (Should I worry about how I will disconnect the application in the future? Will Laravel + Vue for the better?) How your team will work (does the frontend command really need to configure laravel or do they need just worry about the interface code?) etc.

Not sure if I answered your question, if not, leave a comment.

+7
source

You did not find anything clear, because in reality there is nothing to talk about, other than "What do you like about your understanding and the needs of the project ." If you find yourself very insecure, feel free to dive into what makes sense to you, and then adjust the structure again when you gain more experience.

Also, read books on systems architecture, they will help a lot.


Is it possible to use only laravel as a data API, and keep Vue separate from Laravel?

So, I assume you mean SPA? Honestly, if your application is small, then I see that everything is in order.

Large applications are generally difficult to maintain if they are SPA.

Read: https://medium.com/@NeotericEU/single-page-application-vs-multiple-page-application-2591588efe58

If you end up using Laravel as the API endpoint, then use the stripped-down version, Lumen , because it comes without a blade and a few other things. Lumen is versionless to act as an API endpoint.


The best approach to implementing hybrids SPA and MPA.

From my experience, trying to build 4+ projects as hybrids, this is what I found the most optimal structure:

My example will be about an application that saves Messages.

1. Use the repository design template.

This will save you from a headache while saving your code and keeping the concept of DRY (Do not Repeat Yourself) in your code.

  • Create directory App\Repositories\

Create a new PostsRepository class. This will be the one that communicates with the database and contains most of the logic.

  • Create the App\Services\ directory

Create a new PostsService class. This constructor will have a PostsRepository in its constructor.

The class of service will be a single processing that accepts user input, regardless of the web controller or API controller.

 <?php namespace App\Service; use App\Repositories\PostsRepository; class PostsService; { protected $repository; public function __construct(PostsRepository $repository) { $this->repository = $repository; } } 
  • Make a separation between Web controllers and APIs.

For web controllers, you create a controller as usual:

php artisan make:controller PostsController

For API controllers, you create a controller inside the Api folder.

php artisan make:controller Api\PostsController

The last command will create the directory App \ Http \ Controllers \ Api and add a controller to it.

summarizing

Now we have different controllers for returning the results corresponding to the starting point (web / api).

We have services that both (web / api) controllers send their data for verification (and have an action taken by the repository).

Examples:

 <?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', // ]); } } 

In our PostsRepository, we actually call methods that store data. For instance. Post::insert($request); .

2. Allocation of the API group

 Route::prefix('api/v1')->middleware('auth')->group(function() { Route::post('posts/store', 'Api\ PostsController@store ')->name('api.posts.store'); }); 

Providing API routes ->name() helps when running phpunit tests.

3. Types of clicks

Those that should be easily removed.

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 

4. Vue structure.

https://github.com/pablohpsilva/vuejs-component-style-guide

So, those Vue components can live in resources/assets/js/components/posts/ , where inside /posts/ I would have folders called IndexPage , CreateModal , EditModal with each folder having its .vue and README.md .

I would use <posts-index-page> in index.blade.php and, if I want, in <post-create-modal> and <edit-post-modal> .

All vue components will use the API endpoint specified in our routes file.

+2
source

Source: https://habr.com/ru/post/1274680/


All Articles