使用 SSR 和 Laravel 在 Vue 上进行路由
Routing on Vue with SSR and Laravel
我正在学习 Vue,但在尝试使用 Laravel 将其设置为完整的 front-end 时遇到了困难,在我的场景中,我已经使用 Laravel 和 [= 创建了一个用于测试的个人博客56=] 引擎和 Vue 的一些组件,似乎工作正常。
我正在尝试更上一层楼,删除 Blade 并让 Laravel 作为 API 后端,并将 Vue 设置为带有 SSR 的完整前端,基本设置有效,我的意思是我可以调用 Vue,使用带有节点或 PHPv8 的 SSR 来渲染它,我遇到的问题是在路由系统上,认为 blade 方式我无法存档相同的结果,在 blade 上我使用默认值作为主布局并为每个 post、页面、博客等导入它...
示例:
resources/views/layouts/master.blade
<!DOCTYPE html>
<html dir="ltr" lang="{{ app()->getLocale() }}">
<head>
@include('partials._head')
</head>
@if(View::hasSection('body')) {{-- Load Custom Body --}}
<body @section('body')>
@else
<body>
@endif
@yield('content')
@include ('partials._javascripts')
@section('scripts')
</body>
</html>
所以我每页调用一个动态标题/post、一个动态内容、一个基本的 javascripts(bootstrap、vue、fontawesome 等...)和自定义 'scripts'每页 / posts.
使用图书馆:
https://github.com/spatie/laravel-server-side-rendering
我可以让 SSR 使用 node 或 PHPv8,但是 vue-route 永远不会调用所需的页面,我的设置是:
resources/assets/js/app.js
import Vue from 'vue';
import App from './layouts/App';
import axios from 'axios';
import store from './store';
import router from './router';
import navbar from './components/navbar';
import posts from './components/posts';
import sidebar from './components/sidebar';
import footer from './components/footer';
import BlogIndex from './views/blog/BlogIndex';
export default new Vue({
store,
router,
navbar,
posts,
sidebar,
footer,
BlogIndex,
render: h => h(App),
});
resources/assets/js/entry-client.js
import app from './app';
app.$mount('#app');
resources/assets/js/entry-server.js
import app from './app';
import renderVueComponentToString from 'vue-server-renderer/basic';
app.$router.push(context.url);
renderVueComponentToString(app, (err, html) => {
if (err) {
throw new Error(err);
}
dispatch(html);
});
resources/assets/js/router.js
// router.js
import Vue from 'vue';
import VueRouter from 'vue-router';
import Home from './components/Home';
import BlogIndex from './views/blog/BlogIndex';
Vue.use(VueRouter);
const routes = [
{ path: '/', name: 'home', component: Home },
{ path: '/blog', name: 'blog', component: BlogIndex },
];
export default new VueRouter({
mode: 'history',
routes,
});
resources/assets/js/store.js
import Vue from 'vue';
import uniq from 'lodash/uniq';
import Vuex, { Store } from 'vuex';
Vue.use(Vuex);
export default new Store({
state: {
},
getters: {
},
mutations: {
},
});
resources/assets/js/views/blog/BlogIndex.vue
<template>
<div class="container">
<navbar></navbar>
<posts></posts>
<sidebar></sidebar>
<footer></footer>
</div>
</template>
<script>
export default {
name: "BlogIndex",
components: {
}
}
</script>
<style scoped>
</style>
app/Http/Controllers/VueSSRController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\File;
use Illuminate\Routing\Route;
class VueSSRController extends Controller
{
public function __invoke()
{
return view('layouts.vue');
}
}
resources/views/layouts/vue.blade.php
<!DOCTYPE html>
<html dir="ltr" lang="{{ app()->getLocale() }}">
<head>
@section('extrajavascripts'){{ asset('js/scripts.min.js') }}@endsection
@include('partials._head')
</head>
@if(View::hasSection('body')) {{-- Load Custom Body --}}
<body @section('body')>
@else
<body>
@endif
{{-- Begin of Vue SSR --}}
{!! ssr('resources/assets/js/server_bundle.min.js')
// Share the packages with the server script through context
//->context('packages', $packages)
// If ssr fails, we need a container to render the app client-side
->fallback('<div id="app"></div>')
->render() !!}
{{-- End of Vue SSR --}}
@include ('partials._javascripts')
@section('scripts')
@show
</body>
</html>
/resources/assets/js/layouts/App.vue
<template>
<div id ="app">
{{ message }}
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
message: 'SSR working.'
}
}
}
</script>
<style scoped>
</style>
所以 SSR 工作正常,问题是 resources/assets/js/router.js 没有加载 resources/assets/js/views/blog/BlogIndex.vue,url/blog 工作,但呈现的组件始终是 /resources/assets/js/layouts/App.vue.
有人会指出我缺少的设置吗?
多谢指教!!!
您应该将 <router-view></router-view>
放在您希望路由器加载的位置。我认为你的情况低于 {{message}}
in App.vue
我正在学习 Vue,但在尝试使用 Laravel 将其设置为完整的 front-end 时遇到了困难,在我的场景中,我已经使用 Laravel 和 [= 创建了一个用于测试的个人博客56=] 引擎和 Vue 的一些组件,似乎工作正常。
我正在尝试更上一层楼,删除 Blade 并让 Laravel 作为 API 后端,并将 Vue 设置为带有 SSR 的完整前端,基本设置有效,我的意思是我可以调用 Vue,使用带有节点或 PHPv8 的 SSR 来渲染它,我遇到的问题是在路由系统上,认为 blade 方式我无法存档相同的结果,在 blade 上我使用默认值作为主布局并为每个 post、页面、博客等导入它...
示例:
resources/views/layouts/master.blade
<!DOCTYPE html>
<html dir="ltr" lang="{{ app()->getLocale() }}">
<head>
@include('partials._head')
</head>
@if(View::hasSection('body')) {{-- Load Custom Body --}}
<body @section('body')>
@else
<body>
@endif
@yield('content')
@include ('partials._javascripts')
@section('scripts')
</body>
</html>
所以我每页调用一个动态标题/post、一个动态内容、一个基本的 javascripts(bootstrap、vue、fontawesome 等...)和自定义 'scripts'每页 / posts.
使用图书馆:
https://github.com/spatie/laravel-server-side-rendering
我可以让 SSR 使用 node 或 PHPv8,但是 vue-route 永远不会调用所需的页面,我的设置是:
resources/assets/js/app.js
import Vue from 'vue';
import App from './layouts/App';
import axios from 'axios';
import store from './store';
import router from './router';
import navbar from './components/navbar';
import posts from './components/posts';
import sidebar from './components/sidebar';
import footer from './components/footer';
import BlogIndex from './views/blog/BlogIndex';
export default new Vue({
store,
router,
navbar,
posts,
sidebar,
footer,
BlogIndex,
render: h => h(App),
});
resources/assets/js/entry-client.js
import app from './app';
app.$mount('#app');
resources/assets/js/entry-server.js
import app from './app';
import renderVueComponentToString from 'vue-server-renderer/basic';
app.$router.push(context.url);
renderVueComponentToString(app, (err, html) => {
if (err) {
throw new Error(err);
}
dispatch(html);
});
resources/assets/js/router.js
// router.js
import Vue from 'vue';
import VueRouter from 'vue-router';
import Home from './components/Home';
import BlogIndex from './views/blog/BlogIndex';
Vue.use(VueRouter);
const routes = [
{ path: '/', name: 'home', component: Home },
{ path: '/blog', name: 'blog', component: BlogIndex },
];
export default new VueRouter({
mode: 'history',
routes,
});
resources/assets/js/store.js
import Vue from 'vue';
import uniq from 'lodash/uniq';
import Vuex, { Store } from 'vuex';
Vue.use(Vuex);
export default new Store({
state: {
},
getters: {
},
mutations: {
},
});
resources/assets/js/views/blog/BlogIndex.vue
<template>
<div class="container">
<navbar></navbar>
<posts></posts>
<sidebar></sidebar>
<footer></footer>
</div>
</template>
<script>
export default {
name: "BlogIndex",
components: {
}
}
</script>
<style scoped>
</style>
app/Http/Controllers/VueSSRController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\File;
use Illuminate\Routing\Route;
class VueSSRController extends Controller
{
public function __invoke()
{
return view('layouts.vue');
}
}
resources/views/layouts/vue.blade.php
<!DOCTYPE html>
<html dir="ltr" lang="{{ app()->getLocale() }}">
<head>
@section('extrajavascripts'){{ asset('js/scripts.min.js') }}@endsection
@include('partials._head')
</head>
@if(View::hasSection('body')) {{-- Load Custom Body --}}
<body @section('body')>
@else
<body>
@endif
{{-- Begin of Vue SSR --}}
{!! ssr('resources/assets/js/server_bundle.min.js')
// Share the packages with the server script through context
//->context('packages', $packages)
// If ssr fails, we need a container to render the app client-side
->fallback('<div id="app"></div>')
->render() !!}
{{-- End of Vue SSR --}}
@include ('partials._javascripts')
@section('scripts')
@show
</body>
</html>
/resources/assets/js/layouts/App.vue
<template>
<div id ="app">
{{ message }}
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
message: 'SSR working.'
}
}
}
</script>
<style scoped>
</style>
所以 SSR 工作正常,问题是 resources/assets/js/router.js 没有加载 resources/assets/js/views/blog/BlogIndex.vue,url/blog 工作,但呈现的组件始终是 /resources/assets/js/layouts/App.vue.
有人会指出我缺少的设置吗?
多谢指教!!!
您应该将 <router-view></router-view>
放在您希望路由器加载的位置。我认为你的情况低于 {{message}}
in App.vue