这是PHP Advent Calendar 2018的第16天文章。
背景
PHP通常被称为模板引擎,但是如今有各种模板引擎,例如Twig,Smarty和胡须。
但是,在最近的Web领域中,按功能作为组件来分离职责的范式正在从HTM,CSS和JavaScript的权力分离中转移出来。
作为支持该技术的技术,已经建立了一种在称为"服务器端渲染"的服务器上执行JavaScript并建立响应的方法。
我觉得今年NuxtJS的反应特别大。
好吧,即使您想进行SSR,在引入Nuxt时也必须克服一些障碍,我觉得这有点困难。
我希望至少可以像模板引擎一样在PHP中使用Vue ...是吗?
本文将告诉您如何为此使用PHP尝试SSR Vue。
在PHP
中执行JavaScript
当前有两种在PHP中执行JavaScript的方法。
- V8J
- phpExecJs
在PHP V8Js中的SSR文章中详细解释了这些内容。
另外,如果您使用名为Baracoa的库,那么使用React的SSR似乎很容易,因此,如果您有兴趣,请阅读它。
这次我将使用V8Js渲染Vue。
如何使用Vue
进行SSR
Vue 2.x中的服务器端渲染在《 Vue SSR指南-在非Node.js环境中使用》中进行了描述。
render.php
1 2 3 4 5 6 7 8 9 10 11 | <?php $vue_source = file_get_contents('/path/to/vue.js'); $renderer_source = file_get_contents('/path/to/vue-server-renderer/basic.js'); $app_source = file_get_contents('/path/to/app.js'); $v8 = new V8Js(); $v8->executeString('var process = { env: { VUE_ENV: "server", NODE_ENV: "production" }}; this.global = { process: process };'); $v8->executeString($vue_source); $v8->executeString($renderer_source); $v8->executeString($app_source); |
app.js
1 2 3 4 5 6 7 8 9 10 11 12 | // app.js var vm = new Vue({ template: `<div>{{ msg }}</div>`, data: { msg: 'hello' } }) // `vue-server-renderer/basic.js` によってエクスポーズ renderVueComponentToString(vm, (err, res) => { print(res) }) |
评论
从文件中以文本形式读取
创建一个
按
它比React更复杂。
vue服务器渲染器
vue-server-renderer是用于SSRing Vue的实用程序。您可以在服务器环境上运行Vue并将其输出为HTML文本。
在
尝试实施
V8准备
我认为这是最艰巨的任务...
如今,这很方便,我使用Docker是因为有一个可以使用V8的映像。
V8Js docker映像
目录结构
这次我做到了。
我在app.php中输出HTML,并将复杂的渲染过程推到另一个文件中。
关于视图,它与webpack捆绑在一起,但是VueCLI等并未用于轻松显示结构。
1 2 3 4 5 6 7 8 9 10 11 | +- src | +- Renderer.php +- views/ | +- dist/ | +- src/ | | +- App.vue | | +- index.js | +- package.json | +- webpack.config.js +- app.php +- composer.json |
-
app.php -返回HTML的入口点 -
src/Renderer.php -在V8上执行JavaScript并返回结果的人 -
views/src/index.js --renderVueComponentToString入口点 -
views/src/App.vue --Vue文件
在PHP端实现
创建一个调用Renderer的别名。
composer.json
1 2 3 4 5 6 7 | { "autoload": { "psr-4": { "VueSSR\": "src/" } } } |
渲染器将初始化
调用
在
src / Renderer.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | <?php namespace VueSSR; use V8Js; class Renderer { private $nodePath; private $vueSource; private $rendererSource; private $v8; /** * @param string $nodeModulesPath * @return void */ public function __construct (string $nodeModulesPath) { $this->nodePath = $nodeModulesPath; $this->v8 = new V8Js(); } /** * @param string $entrypoint */ public function render(string $entrypoint, array $data) { $state = json_encode($data); $app = file_get_contents($entrypoint); $this->setupVueRendderer(); $this->v8->executeString("var __PRELOAD_STATE__ = ${state}; this.global.__PRELOAD_STATE__ = __PRELOAD_STATE__;"); $this->v8->executeString($app); } private function setupVueRendderer() { $prepareCode = <<<'EOT' var process = { env: { VUE_ENV: "server", NODE_ENV: "production" } }; this.global = { process: process }; EOT; $vueSource = file_get_contents($this->nodePath . 'vue/dist/vue.js'); $rendererSource = file_get_contents($this->nodePath . 'vue-server-renderer/basic.js'); $this->v8->executeString($prepareCode); $this->v8->executeString($vueSource); $this->v8->executeString($rendererSource); } } |
准备HTML输出。
您可以通过执行以下操作将其用作部分。
app.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <?php require_once "vendor/autoload.php"; use VueSSR\Renderer; $renderer = new Renderer('views/node_modules/'); ?> <!doctype html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width"> Example SSR Vue on PHP </head> <body> <?php $renderer->render('./views/dist/main.bundle.js', [ 'message' => 'hello vue!' ]); ?> </body> </html> |
查看实施
建立依赖关系。
1 2 | npm install --save vue vue-server-renderer npm install -D webpack webpack-cli vue-loader vue-template-compiler |
使用WebPack设置构建。这次只有一个入口点,但是可以将多个入口点设置到单独的页面。
现在将其输出到
视图/ webpack.config.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | const path = require('path') const VueLoaderPlugin = require('vue-loader/lib/plugin') module.exports = { entry: './src', output: { path: path.resolve('./dist'), filename: '[name].bundle.js', }, module: { rules: [ { test: /\.vue$/, use: 'vue-loader' }, ] }, plugins: [ new VueLoaderPlugin(), ] } |
它读取
此时,从服务器接收到
这使您可以查看通过
视图/ src / index.js
1 2 3 4 5 6 7 8 9 | import App from './App.vue' App.propsData = __PRELOAD_STATE__ var vm = new Vue(App); renderVueComponentToString(vm, (err, res) => { if (err) throw new Error(err); print(res) }) |
是的,这是Vue文件。
如您所见,您可以使用
views / src / App.vue
1 2 3 4 5 6 7 8 9 10 11 | <template> <p>{{message}}</p> </template> <script> export default { props: { message: { type: String } } } </script> |
概要
我介绍了如何使用PHP进行SSR VueJS。
目前这并不容易,但是如果您使用PHP并想尝试Vue,则可能会发现一些新东西。
这次引入的代码发布在名为example-php-ssr-vue的存储库中,因此,如果您有兴趣,请阅读它。