Laravel VueJS: building multi page app without resorting to single page application ( SPA ) approach

廉价感情. 提交于 2020-01-05 07:16:50

问题


I am trying to build a Laravel 5.5 + VueJs multi page app. I do not want to use SPA (Single Page Application) approach to make it seem to be a multi page app.

This is the case with the registration page at the URL /register. With the command php artisan make:auth I get the registration related files. The scenarios is :

In web.php, I have :

Auth::routes();

In app.js, I have :

window.Vue = require('vue');
const app = new Vue({
    el: '#app',
    components: {
        Register: require('./components/Register.vue')
    }
});

My layout.blade.php resides within resources/views/ folder and has the following content :

    <div id="app">

                <?php
                  var_dump($component);
                ?>
                @if (isset($component))
                    <component :is={{ $component }} >
                        @endif

                        @yield('content')

                        @if (isset($component))
                    </component>
                @endif
   </div>

The register.blade.php file has the content :

@extends('layout', ['component' => 'Register'])

@section('content')

@endsection

Register.vue stays inside resources/js/components/ and has the following content :

<template>
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <div class="panel panel-default">
                    <div class="panel-heading">Example Component</div>

                    <div class="panel-body">
                        I'm an example component!
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        mounted() {
            console.log('Register Component mounted.')
        }
    }
</script>

So my intended work flow is: first the register.blade.php will be called that inherits layout.blade.php and sends as data the Register component which is supposed to be rendered there.

I myself also do not know how the register.blade.php will have the component Register as parameter in the data at the line :

@extends('layout', ['component' => 'Register'])

And while viewing the page source, I even do not see the app.js file being included in the page.

Of course, I run the npm run dev command before testing the page every time.

Question 1 : What is wrong with the approach outlined above ? What should be the proper way however ?

EDIT:

My webpack.mix.js has:

let mix = require('laravel-mix');
    mix.js('resources/assets/js/app.js', 'public/js')
        .styles([

            'resources/assets/css/style.css'

        ], 'public/css/style.css')
    ;

mix.options({
    extractVueStyles: 'public/css/vue-style.css'
});

EDIT2: In the page, I see no content from the Register component . I forgot to mention it before.

EDIT3: Question 2: Is Laravel+VueJs combination not meant for MPA (multi page application) in true sense of the term ?


回答1:


I don't think it's very easy to give an answer to your question, so I will share my experience. At the beginning I was implementing Vue.js in the same way you do so:

  • Multipage app
  • Every page has it's own components
  • Every time the user moves to another page, potentially a new js file is loaded.

It was a complete failure. At the beginning I was using a single app.js file, but I was loading tons of useless components for a single form... Why do I have to load the whole application when I need only two or three components? So I had to create tons of xxx-app.js files and break the DRY principle. It wasn't the best... But it worked and was easy to implement.

SIDE NOTE: I wasn't using any kind of file chunking or other systems that may have removed this kind of problem. I was at the very beginning with VueJS development. Probably at the time I didn't even know it was possible.

The structure was something like:

page1.blade.php

@extends('my.layout')

@push('scripts')
    <script src="asset('page1-app.js')"></script>
@endpush

@section('content')
    <page1-component attr1="{{ $attr1 }}" [...]></page1-component>
@endsection

As you can see the structure is kinda simple:

  • Extend the required layout in order to load the CSS and extra scripts required
  • Push in the scripts stack the Vue instance you need
  • In the content section call the component you need

But the problems were born in the javascript part... I was using 1/3 of the features of modern javascript app development. Everyday a new problem was coming out... First JQuery was useless... Then the technical SEO part was hard to handle... Then the Vuex store logic was replicated and useless when the user reloads the page... In a very short time I realized that this approach was completely wrong...

Well, for the application I was working on at least. So IMHO and as in many cases the answer to your question

What is wrong with the approach outlined above ? What should be the proper way however ?

is It depends.

If you have a small application, easy to maintain and without complex workflow, your solution works... You just have to remember that:

  1. If you include in every page your app.js file but you need only 1 or 2 components it may become a little heavy.
  2. There's a high risk of redundancy.
  3. The initial components state depends on the backend attributes given to the blade view... If something is wrong, the entire application messes up.

If you're facing these problems consider to move to a complete SPA logic... Easier to maintain, you don't have to invent a workaround everyday and so on.

If your application is an "enterprise" solution... Well avoid to mix up Laravel and Vue in a single codebase... Split everything and handle the backend and the frontend as two completely separate entities.



来源:https://stackoverflow.com/questions/59289548/laravel-vuejs-building-multi-page-app-without-resorting-to-single-page-applicat

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!