服务器端渲染是提高整个堆栈应用程序加载速度的好方法。用户在加载站点时会看到一个完整的页面,其中包含可见的内容,而不是一个直到JavaScript运行后才填充的空页面。
使用Laravel作为Vue.js的后端有一个缺点,就是无法在服务器上呈现代码。是什么。Vue.js 2.5.0的发布为非node .js环境(包括PHP、Python、Ruby等)带来了服务器端渲染支持。
在本教程中,我将向您介绍Laravel的设置步骤并演示一个简单的服务器呈现应用程序。在Github上获取此代码。
服务器端渲染的快速概述
如果您不熟悉服务器端呈现(SSR),这里有一个简单的例子:假设我们有一个用组件构建的Vue.js应用程序。如果我们使用浏览器开发工具在页面加载后查看页面DOM,我们将看到我们的完全渲染的应用程序:
<div id="app"> <ul> <li>Component 1</li> <li>Component 2</li> <li> <div>Component 3</div> </li> </ul></div>
但是如果我们查看文档的源文件,即index.html,当它被服务器发送时,你会看到它只有我们的mount元素:
<div id="app"></div>
为什么要有差异?因为JavaScript负责构建页面,而且事实上,JavaScript必须在构建页面之前运行。刚离开服务器,页面将没有内容。
但是对于服务器端呈现,我们的页面包含了浏览器在下载和运行JavaScript之前构建DOM所需的HTML,即页面源看起来像上面的第一个示例。
这是通过在服务器上运行Vue.js应用程序并捕获输出来实现的,然后在将输出发送给用户之前将其注入页面。
使用SSR,您的应用程序不会加载或运行得更快,实际上,由于服务器添加了呈现应用程序的任务,它可能会运行得稍微慢一些。但是页面内容显示得更快,因此用户可以更快地看到engage With页面。
为什么Laravel直到现在还不能做Vue SSR ?
显然,SSR需要服务器上的JavaScript环境,因为Vue应用程序是用JavaScript编写的。对于PHP、Ruby和Python等非node .js后端,必须从服务器派生一个JavaScript沙箱来运行Vue应用程序并生成输出。
v8js是一个允许您在php环境中安装v8 javascript运行时并创建这样一个沙箱的项目。但在VUE版本2.5.0之前,这仍然不够,因为VUE SSR需要某些node.js API才能正确运行。
最近的更新确保了服务器渲染器现在是“环境不可知的”,因此可以在node.js、v8js、nashorn等中运行。
Vue / Laravel SSR演示
现在让我们在Laravel应用程序中获得一个简单的Vue SSR演示。
环境
php-v8js是PHP扩展,可以访问Google的V8 Javascript引擎。毫无疑问,使用PHP设置Vue SSR最棘手的部分是安装V8J。
如果您对开发操作有一定的了解,您可以尝试自己安装它。如果没有,我建议您使用这个Docker映像并在上面安装Laravel。
安装依赖
一旦扩展工作正常并有了新的laravel项目,就需要同时安装vue和vue服务器渲染器。你需要一个2.5.0的最小版本来获得与环境无关的ssr特性。
npm i --save-dev vue@>=2.5.0 vue-server-renderer@>=2.5.0
vue.js
让我们首先设置一个简单的全堆栈vue.js/laravel应用程序。这还没有任何ssr特性,但我们将奠定我们需要的基础。首先,我们将把app的主要功能放到单个文件组件app.vue中。
resources/assets/js/components/App.vue
<template> <div id="app"> {{ message }} </div> </template> <script> export default { data() { return { message: 'Hello World' } } } </script>
我们的应用程序入口文件app.js只负责呈现组件并将其挂载到模板中。这里使用呈现函数而不是DOM模板非常重要,原因很快就会清楚。
resources/assets/js/app.js
import App from './components/App.vue'; import Vue from 'vue'; new Vue({ el: '#app' render: h => h(App) });
组合配置
让我们设置一个构建条目文件的Mix配置。注意,我还覆盖了默认的Vue构建,以使用仅运行时构建。因为我们使用渲染函数和单文件组件,所以不需要模板渲染器。
webpack.mix.js
let mix = require('laravel-mix'); mix .js('resources/assets/js/app.js', 'public/js') ; mix.webpackConfig({ resolve: { alias: { 'vue$': 'vue/dist/vue.runtime.common.js' } } });
完成后,您应该能够构建Vue.js应用程序:
$ npm run dev ## Outputs to public/js/app.js
Blade view
我们需要一个刀片模板来将Vue应用程序交付到浏览器。确保包含一个id为app的空div,它将用作mount元素。另外,还要包括构建脚本。
resources/views/app.blade.php
<!doctype html> <html lang="{{ app()->getLocale() }}"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Vue/Laravel SSR App</title> </head> <body> <div id="app"></div> <script src="{{ asset('js/app.js') }}" type="text/javascript"></script> </body></html>
控制器和路线
让我们创建一个新的控制器类,它将很快包含用于服务器呈现应用程序的逻辑。
$ php artisan make:controller AppController
首先,我们将创建一个方法get返回我们的app视图:
app/Http/Controllers/AppController.php
<?php namespace App\Http\Controllers; class AppController extends Controller { public function get() { return view('app'); } }
我们将为根路径添加一个web路由,它调用这个控制器方法:
routes/web.php
Route::get('/', 'AppController@get');
完成后,我们现在应该能够查看我们的简陋的全堆栈应用程序:
服务器端呈现
我们在沙箱中运行的Vue.js应用程序必须与我们在浏览器中运行的应用程序稍有不同,因为尽管使用了相同的语言,但是这些环境非常不同。例如,沙箱中没有窗口或文档对象。
因此,我们需要两个构建。它们将尽可能地相似,但是会有一些小的差异。我们将在app.js中保留任何通用(即通用)代码,但是任何特定于环境的代码都将进入我们将很快创建的新条目文件中。
在app.js中,让我们从Vue配置中删除el属性,因为它在服务器环境中没有意义,因为应用程序没有要挂载的文档。我们还会让这个文件导出app实例它可以导入到我们的新条目文件中。
resources/assets/js/app.js
export default new Vue({ render: h => h(A<mark style="color:transparent">本文来源gaodaimacom搞#^代%!码&网*</mark>pp) });
输入文件
现在我们需要创建两个新的条目文件,一个用于浏览器(客户机),一个用于服务器。
$ touch resources/assets/js/entry-client.js resources/assets/js/entry-server.js
客户端条目将简单地重新实现我们刚刚从app.js中删除的功能,即它将导入通用应用程序并将其挂载到模板中。
resources/assets/js/entry-client.js
import app from './app' app.$mount('#app');
服务器条目文件更有趣一些。首先,它调用一个全局方法rendervuecomponenttostring。此方法由vue服务器呈现程序公开,我们将很快将其引入ssr设置。其次,它调用方法print。此方法是v8js api的一部分,是将javascript沙箱中的内容返回php环境的机制。
resources/assets/js/entry-server.js
import app from './app' renderVueComponentToString(app, (err, res) => { print(res); });
我们现在需要更新我们的Mix配置,这样我们就可以从两个新的输入文件中得到应用程序的每个版本的构建:
webpack.mix.js
mix .js('resources/assets/js/entry-client.js', 'public/js') .js('resources/assets/js/entry-server.js', 'public/js') ;
在再次运行npm运行dev之后,您当然会有两个构建文件。我们需要更新我们的刀片视图,以确保新的客户端构建文件正在加载,而不是app.js:
resoures/views/app.blade.php
<script src="{{ asset('js/entry-client.js') }}" type="text/javascript"></script>
如果在浏览器中刷新页面,应该还看不到行为上的差异。
Laravel
现在我们终于开始讨论服务器端呈现功能。添加一个新的方法渲染到AppController,如下所示:
-
vue-server-renderer模块和应用程序的服务器构建从文件系统加载。
-
打开输出缓冲。这意味着从脚本发送的任何输出都在内部捕获,而不是打印到屏幕上。
-
将一些必要的环境变量传递给V8Js。
-
然后执行呈现程序代码和服务器构建文件。记住,在entry-server.js中,我们使用print方法来输出一些东西。这将由输出缓冲区捕获。
-
返回缓冲区内容并删除当前输出缓冲区。
app/Http/Controllers/AppController.php
<?php namespace App\Http\Controllers; use Illuminate\Support\Facades\File; class AppController extends Controller { private function render() { $renderer_source = File::get(base_path('node_modules/vue-server-renderer/basic.js')); $app_source = File::get(public_path('js/entry-server.js')); $v8 = new \V8Js(); ob_start(); $js = <<<EOT var process = { env: { VUE_ENV: "server", NODE_ENV: "production" } }; this.global = { process: process }; EOT; $v8->executeString($js); $v8->executeString($renderer_source); $v8->executeString($app_source); return ob_get_clean(); } public function get() { $ssr = $this->render(); return view('app', ['ssr' => $ssr]); } }
render返回的值将是应用程序的服务器渲染输出。它是一个HTML字符串。现在,我们将把它分配给一个模板变量并将其发送到视图。确保使用{!!跳过转义字符串。! !}大括号,使HTML按原样打印。
resoures/views/app.blade.php
<body> {!! $ssr !!} <script src="{{ asset('js/entry-client.js') }}" type="text/javascript"></script> </body>
这样,服务器端呈现现在就可以工作了!但是,如果您加载应用程序,您可能不会注意到任何区别,因为在本地服务器上加载页面的改进是无法察觉的。要确认它是否工作,请查看文档的源代码,您将看到:
我们的页面中没有空的<div id=“app”>,而是有实际的内容。请注意Vue服务器渲染器添加的特殊属性:data server rendered=“true”。这样,当Vue实例装载时,而不是尝试重新构建内容时,它将尝试在其上装载。
结论
缺乏服务器端渲染是使用Laravel作为Vue.js后端的最大缺点之一。与Node.js相比,它仍然是二流的,因为需要一个沙盒,但现在它很有用。
英文原文地址:https://vuejsdevelopers.com/2017/11/06/vue-js-laravel-server-side-rendering/
以上就是使用laravel&vue.js 2.5进行服务器端渲染的详细内容,更多请关注gaodaima搞代码网其它相关文章!