使用Laravel作为您的Vue的后端js应用是一个新的优势。请继续阅读,了解如何使用这两个框架来处理SSR。
服务器端渲染是一种很好的方式来增加你的全栈应用程序的加载速度感知。当用户加载你的站点时,他们会得到一个完整的页面,而不是在JavaScript运行之前没有填充的空白页面。
使用Laravel作为Vue的后端的缺点之一。js是无法让服务器呈现您的代码。是什么。Vue的释放js 2.5.0将服务器端呈现支持引入到非节点js环境包括PHP、Python、Ruby等。
在本教程中,我将介绍Laravel的设置步骤,并演示一个简单的服务器呈现应用程序。
注意:本文最初发布在Vue上。js开发者博客2017/11/06。
服务器端呈现的快速概述。
如果您不熟悉服务器端渲染(SSR),这里有一个简单的例子:假设我们有一个Vue。js应用程序内置组件。如果我们使用浏览器dev工具来查看页面加载后的页面DOM,我们将看到我们的完整呈现的应用程序:
Component 1
Component 2
Component 3
但如果我们查看文档的来源,即索引html,当它被服务器发送时,你会看到它有我们的mount元素:
为什么会出现这种分歧呢?因为JavaScript负责构建页面,而且实际上,JavaScript必须在创建页面之前运行。刚离开服务器,页面将没有内容。
但是,在服务器端呈现的情况下,我们的页面包含了浏览器在JavaScript下载和运行之前构建DOM所需的HTML,即页面源代码看起来像上面的第一个例子。这是通过运行Vue实现的。服务器上的js应用程序捕获输出,然后将输出注入到页面,然后再发送给用户。
使用SSR时,你的应用程序不会加载或运行得更快,实际上它可能会运行得稍微慢一些,因为服务器已经完成了呈现应用程序的任务。但是页面内容会更快地显示出来,因此用户可以更快地看到页面。
为什么拉拉维尔到现在还不能做?
显然,SSR需要服务器上的JavaScript环境,因为Vue应用程序是用JavaScript完成的。non-Node。js的后台如PHP、Ruby和Python,必须从服务器生成一个JavaScript沙箱来运行Vue应用程序并生成输出。
V8Js是一个项目,允许您在一个PHP环境中安装V8 JavaScript运行时,并创建这样一个沙箱。但是在Vue版本2.5.0之前,这仍然不够,因为Vue SSR需要某个节点。js api可以正常运行。最近的更新确保了服务器渲染器现在是“环境无关的”,因此可以在节点中运行js、V8Js Nashorn等等。
Vue / Laravel SSR演示
现在让我们在一个Laravel应用程序中得到一个Vue SSR的简单演示。
环境
PHP -v8js是PHP扩展,可以访问谷歌的V8 JavaScript引擎。毫无疑问,用PHP设置Vue SSR最棘手的部分是安装V8Js。由于我的Linux知识有限,实际上,它花了我几个小时才让它工作。
如果您对DevOps有一点技巧,您可以尝试自己安装它。如果没有,我建议您使用这个Docker映像并在其上安装Laravel。
安装依赖关系
一旦您有了扩展工作并拥有一个新的Laravel项目,您就需要同时安装Vue和Vue -server-renderer。您将需要一个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.vue。
resources/assets/js/components/App.vue
{{ message }}
export default {
data() {
return {
message: 'Hello World'
}
}
}
我们的应用程序输入文件,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)
});
组合配置
让我们设置一个混合配置来构建条目文件。注意,我还重写了默认的Vue构建,以使用运行时构建。由于我们使用呈现函数和单文件组件,所以不需要模板渲染器。
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'
}
}
});
完成之后,您就可以构建Vu.js应用:
$ npm run dev
## Outputs to public/js/app.js
叶片视图
我们需要一个刀片模板来将我们的Vue应用程序交付给浏览器。确保包含一个带有id应用程序的空div,它将作为挂载元素。此外,还包括构建脚本。
resources/views/app.blade.php
getLocale() }}">
Vue/Laravel SSR App
控制器和路由
让我们创建一个新的控制器类,它将很快包括服务器呈现应用程序的逻辑。
$ php artisan make:controller AppController
首先,我们将创建一个方法get来返回我们的app视图:
app/Http/Controllers/AppController.php
namespace App\Http\Controllers;
class AppController extends Controller
{
public function get() {
return view('app');
}
}
我们将为根路径添加一个web路径,该路径调用此控制器方法:
routes/web.php
Route::get('/', 'AppController@get');
这样做之后,我们现在就可以看到我们简陋的全栈应用程序了:
服务器端呈现
Vue在sandbox中运行的js应用程序必须与我们在浏览器中运行的应用程序稍有不同,因为使用相同的语言,这些环境非常不同。例如,在沙箱中没有窗口或文档对象。
因此,我们需要两个构建。这些将会尽可能地相似,但会有一些细微的差别。我们将在app.js中保留任何常见的(即通用的)代码,但是任何特定于环境的代码都将进入我们即将创建的新条目文件。
在app.js中,让我们从Vue配置中移除el属性,因为它在服务器环境中是毫无意义的,因为该应用程序没有要挂载的文档。我们还将使这个文件导出一个函数,该函数返回应用程序的一个新实例,该实例可以导入到我们的新条目文件中。
resources/assets/js/app.js
export function createApp() {
return new Vue({
render: h => h(App)
});
}
入口文件
我们现在需要创建两个新的条目文件,一个用于浏览器(客户机),另一个用于服务器。
$ touch resources/assets/js/entry-client.js resources/assets/js/entry-server.js
客户端条目将简单地重新实现我们刚刚从app.js中删除的功能,即它将导入通用应用程序并将其挂载到模板中。
resources/assets/js/entry-client.js
import { createApp } from './app'
createApp().$mount('#app');
服务器条目文件更有趣一些。首先,它调用一个全球renderVueComponentToString方法。这个方法是由vue-server-renderer公开的,我们将很快引入SSR设置。其次,它调用了一个方法打印。该方法是V8Js API的一部分,也是从JavaScript沙箱返回到PHP环境的机制。
resources/assets/js/entry-server.js
import { createApp } from './app'
renderVueComponentToString(createApp(), (err, res) => {
print(res);
});
我们现在需要更新我们的混合配置,这样我们就可以从两个新的条目文件中得到应用程序的每个版本:
mix
.js('resources/assets/js/entry-client.js', 'public/js')
.js('resources/assets/js/entry-server.js', 'public/js')
;
在运行npm运行dev之后,当然,您将有两个构建文件。我们需要更新我们的Blade视图,以确保新客户端构建文件被加载而不是加载。
resoures/views/app.blade.php
如果您在浏览器中刷新页面,则在行为上应该看不到任何差异。
Laravel
现在,我们终于了解了服务器端呈现功能。在AppController中添加一个新方法,它的工作方式如下:
该应用程序的“vue-server-renderer模块”和“服务器构建”都是从文件系统中加载的。
输出缓冲被打开。这意味着从脚本发送的任何输出都是在内部捕获的,而不是被打印到屏幕上。
将一些必要的环境变量传递给V8Js。
然后执行renderer代码和服务器构建文件。记住,在输入服务器。我们使用打印方法输出一些东西。这将被输出缓冲区捕获。
返回缓冲区内容并删除当前输出缓冲区。
app/Http/Controllers/AppController.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();
$v8->executeString('var process = { env: { VUE_ENV: "server", NODE_ENV: "production" }}; this.global = { process: process };');
$v8->executeString($renderer_source);
$v8->executeString($app_source);
return ob_get_clean();
}
public function get() {
$ssr = $this->render();
return view('app', ['ssr' => $ssr]);
}
}
从渲染返回的值将是我们的应用程序的服务器渲染输出。它是一个HTML字符串。我们现在将其分配给一个模板变量,并将其发送到视图。一定要使用{!!! !大括号,因此HTML是按原样打印的。
resources/views/app.blade.php
{!! $ssr !!}
这样,服务器端呈现就开始工作了!但是,如果加载应用程序,您可能不会注意到任何不同,因为本地服务器上的页面加载改进不会被察觉。要确认它的工作,查看文档的源代码,您将看到:
而不是空的
, 我们在页面中有实际的内容。请注意vue-server-renderer添加的特殊属性:数据服务器渲染="true"。这是这样的,当Vue实例挂载时,而不是试图重新构建内容,它将尝试挂载它。
结论
服务器端呈现的缺乏是使用Laravel作为Vue的最大缺点之一。js后端。与节点相比,它仍然是二流的。js因为需要一个沙箱,但是它现在很好用。
有关Vue SSR的更多信息,请查看Vue.js端呈现指南。
领取专属 10元无门槛券
私享最新 技术干货