问题
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:
- If you include in every page your
app.js
file but you need only 1 or 2 components it may become a little heavy. - There's a high risk of redundancy.
- 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