简体   繁体   English

Vue.js:在laravel中实现MPA(多页面应用程序)的最佳方式

[英]Vue.js : Best way to implement MPA(Multi page app) in laravel

I have been looking around for quite a time, But didn't got anything convening. 我一直在四处寻找,但没有得到任何召集。

What will be the best approach and practice to implement Vue MPA architecture in laravel. 在laravel中实现Vue MPA架构的最佳方法和实践是什么。

Searched for quite a bit. 搜索了很多。 But there isn't anything which will give you a clear idea. 但没有什么能给你一个清晰的想法。 Your answer will help alot, Please make it brief. 你的回答很有帮助,请简要说明。

It will also be helpful to answer the point : 回答这一点也很有帮助:

  • Is it a good idea to use just laravel as a data API, And keep Vue separate from laravel ? 使用laravel作为数据API是一个好主意,并将Vue与laravel分开?
  • Best approach for implementing hybrid of SPA and MPA. 实现SPA和MPA混合的最佳方法。

Some options that I've already used: 我已经使用过的一些选项:

Use Laravel to render the "main view" + connect vue.js application. 使用Laravel渲染“主视图”+ connect vue.js应用程序。

Basically laravel will render the Vue application and every request goes throught an API. 基本上laravel将呈现Vue应用程序,并且每个请求都通过API。

  1. Easy to setup 易于设置
  2. Authentication + user validation is easier (you can use laravel session manager for that - don't need to build/use tokens or whatever. "No need to worry about your application state".) 身份验证+用户验证更容易(您可以使用laravel会话管理器 - 不需要构建/使用令牌或其他任何东西。“无需担心您的应用程序状态”。)
  3. Easy to "disconnect" from Laravel - if you choose in the future to decouple the SPA application. 轻松与Laravel“断开” - 如果您将来选择解耦SPA应用程序。

Use laravel (or lumen) only as an API, and on another server render a SPA. 仅将laravel(或流明)用作API,并在另一台服务器上呈现SPA。

This can take more time, since you'll need to setup an extra server, prepare cross-origin, etc. 这可能需要更多时间,因为您需要设置额外的服务器,准备跨源等。

  1. Also easy to setup, but can take more time than option #1 也很容易设置,但可能比选项#1花费更多的时间
  2. You'll need to create something for user validation/state management, etc. 您需要为用户验证/状态管理等创建一些内容。
  3. Easy to place into laravel, if you decide in the future to use "only one app". 如果您决定在将来使用“仅一个应用程序”,则很容易放入laravel。
  4. Can be easier to maintain/scale (if you have a frontend team, they don't need to worry about laravel - same for your "laravel team", they "won't need to worry" about the frontend) 可以更容易维护/扩展(如果你有一个前端团队,他们不需要担心laravel - 同样对于你的“laravel团队”,他们“不需要担心”前端)

Laravel + Vue = "one application" Laravel + Vue =“一个应用程序”

You can use Laravel to render all views + vuejs for components/elements in the page. 您可以使用Laravel渲染页面中组件/元素的所有视图+ vuejs。

  1. Easy to setup. 易于设置。 You have laravel + vuejs, and they are already prepared to be used together. 你有laravel + vuejs,他们已经准备好一起使用了。 https://laravel.com/docs/5.5/frontend#writing-vue-components https://laravel.com/docs/5.5/frontend#writing-vue-components
  2. Not so easy to decouple. 解耦并不容易。 In this case you'll need to create the same views for vue.js. 在这种情况下,您需要为vue.js创建相同的视图。 This can take time. 这可能需要时间。
  3. This is the "traditional web development" (in my opinion). 这是“传统的网络开发”(在我看来)。 If I had to start a project like this today, I wouldn't create all pages in Vue.js + something in Laravel (Controller + new route) to render this view. 如果我今天必须启动这样的项目,我不会在Vue.js中创建所有页面+ Laravel中的所有页面(Controller +新路线)来渲染此视图。 If you do this (again - my opinion), it's just extra work. 如果你这样做(再次 - 我的意见),这只是额外的工作。 If you are worried about SEO, there are "fallbacks"/extra options. 如果你担心SEO,有“后备”/额外选项。

-- -

All options are testable + scalable. 所有选项都是可测试的+可扩展的。

It also depends on how you start ( Should I worry about how I'll decouple the app in the future? Laravel + Vue will be for good? ), how your team will work ( Does the frontend team really needs to setup laravel or they only need to worry about the frontend code? ), etc. 这也取决于你如何开始( 我应该担心将来如何解开应用程序?Laravel + Vue会很好吗? ),你的团队将如何工作( 前端团队是否真的需要设置laravel或者他们只需要担心前端代码? )等

Not sure if i answered your question, if not, please leave a comment. 不确定我是否回答了您的问题,如果没有,请发表评论。

You haven't found anything clear because there isn't really anything to talk about other than 'What feels right to your understanding and project needs '. 你还没有找到任何明确的东西,因为除了“对你的理解和项目需求感觉合适”之外,没有什么可说的。 If you found yourself very unsure, feel free to dive into doing whatever makes sense to you and then re-adjust the structure when you gain more experience. 如果你发现自己非常不确定,可以随意潜入对你有意义的事情,然后在获得更多经验时重新调整结构。

Also, read books about system architecture, those will help a lot. 另外,阅读有关系统架构的书籍,这些将有很大帮助。


Is it a good idea to use just laravel as a data API, And keep Vue separate from Laravel? 使用laravel作为数据API是一个好主意,并将Vue与Laravel分开?

By this, I'm assuming you mean a SPA? 通过这个,我假设你的意思是SPA? Honestly, if your application is small, then I see this is fine. 老实说,如果你的申请很小,那么我觉得这很好。

Larger applications tend to be difficult to maintain if they were SPA. 如果是SPA,则较大的应用程序往往难以维护。

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

If you end up using Laravel as an API endpoint, then use the stripped down version of it, Lumen , because it comes without Blade and few other stuff. 如果你最终使用Laravel作为API端点,那么使用它的精简版Lumen ,因为它没有Blade和其他一些东西。 Lumen is stripped down version to act as an API-endpoint. Lumen被剥离版本作为API端点。


Best approach for implementing hybrid of SPA and MPA. 实现SPA和MPA混合的最佳方法。

From my experience having attempted to build 4+ projects as hybrids, here's what I found the most optimal structure: 根据我尝试将4个以上项目构建为混合项目的经验,以下是我发现的最佳结构:

My example will be about an app that saves 'Posts'. 我的例子是关于保存“帖子”的应用程序。

1. Use a repository design pattern. 1.使用存储库设计模式。

This one will save you a lot of headache in maintaining your code and maintain a DRY (Don't Repeat Yourself) concept on your code. 这个可以让您在维护代码和维护代码中的DRY(不要重复自己)概念时遇到很多麻烦。

  • Create a directory App\\Repositories\\ 创建目录App\\Repositories\\

Make a new class PostsRepository . 创建一个新类PostsRepository This one will be the one communicating with the database and contains most of the logic. 这个将是与数据库通信并包含大部分逻辑的那个。

  • Create the directory App\\Services\\ 创建目录App\\Services\\

Make a new class PostsService . 创建一个新类PostsService This one will have the PostsRepository in its constructor. 这个将在其构造函数中包含PostsRepository

The service class will be one handling taking user's input whether from the Web controller or the API controller. 服务类将是一个处理用户输入的服务类,无论是来自Web控制器还是API控制器。

<?php

namespace App\Service;

use App\Repositories\PostsRepository;

class PostsService;
{
    protected $repository;

    public function __construct(PostsRepository $repository)
    {
        $this->repository = $repository;
    }
}
  • Make a seperation between Web and API controllers. 在Web和API控制器之间进行分离。

For web controllers, you create the controller like usual: 对于Web控制器,您可以像平常一样创建控制器:

php artisan make:controller PostsController

For API controllers, you create the controller to be inside an Api folder. 对于API控制器,您可以将控制器创建在Api文件夹中。

php artisan make:controller Api\\PostsController

The last command will create the directory App\\Http\\Controllers\\Api and have the controller be placed in it. 最后一个命令将创建目录App \\ Http \\ Controllers \\ Api并将控制器放在其中。

Recapping 重述

Now we have different controllers to return results appropriate to the startpoint (web / api). 现在我们有不同的控制器来返回适合起始点(web / api)的结果。

We have services that both the (web / api) controllers send their data to be validated (and have the action taken by the repository). 我们有(web / api)控制器发送其数据以进行验证(并且具有存储库采取的操作)的服务。

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 save the data. 在我们的PostsRepository中,我们实际上调用了保存数据的方法。 Eg Post::insert($request); 例如Post::insert($request); .

2. Dedicate an API group 2.专用API组

Route::prefix('api/v1')->middleware('auth')->group(function() {

    Route::post('posts/store', 'Api\PostsController@store')->name('api.posts.store');

});

Giving API routes a ->name() helps when you make phpunit tests. 在进行phpunit测试时,为API路由提供一个->name()会有所帮助。

3. Blade views 3.刀锋观点

Those are ought to be stripped-down simple. 这些都应该简单明了。

views/posts/index.blade.php : 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. 4. Vue结构。

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

So those Vue components might live in resources/assets/js/components/posts/ where inside /posts/ I'd have folders titled for example IndexPage , CreateModal , EditModal with each folder having its .vue and README.md . 因此,那些Vue的组件可能生活在resources/assets/js/components/posts/哪里里/posts/我不得不名为例如文件夹IndexPageCreateModalEditModal具有它的每个文件夹.vueREADME.md

I'd use the <posts-index-page> in index.blade.php and drop in the <post-create-modal> and <edit-post-modal> whenever I want. 我会在index.blade.php使用<posts-index-page>index.blade.php放入<post-create-modal><edit-post-modal>

All the vue components will use the API endpoint we specified in our Routes file. 所有vue组件都将使用我们在Routes文件中指定的API端点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM