Vue服务端渲染SSR示例如何改写为长尾关键词?

2026-03-31 16:281阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计2270个文字,预计阅读时间需要10分钟。

Vue服务端渲染SSR示例如何改写为长尾关键词?

目录+手写Vue服务端渲染+一.开始vue-ssr之旅+二.采用模板渲染+三.ssr目录创建+四.通过webpack实现Vue项目编译+app.js+client-entry.js+server-entry.js+五.配置客户端打包和服务端打包+六.配置运行脚本

目录
  • 手写Vue服务端渲染
  • 一.开始vue-ssr之旅
  • 二.采用模板渲染
  • 三.ssr目录创建
  • 四.通过webpack实现编译vue项目
    • app.js
    • client-entry.js
    • server-entry.js
  • 五.配置客户端打包和服务端打包
    • 六.配置运行脚本
      • 七.服务端配置
        • 七.通过json配置createBundleRenderer方法
          • 八.集成VueRouter
            • 配置入口文件
            • 配置组件信息
            • 防止刷新页面不存在
            • 保证异步路由加载完成
          • 十.集成vuex配置
            • 在后端更新vuex
            • 在浏览器运行时替换store
            • 需要执行的钩子函数

          手写Vue服务端渲染

          概念:放在浏览器进行就是浏览器渲染,放在服务器进行就是服务器渲染。

          • 客户端渲染不利于 SEO 搜索引擎优化
          • 服务端渲染是可以被爬虫抓取到的,客户端异步渲染是很难被爬虫抓取到的
          • SSR直接将HTML字符串传递给浏览器。大大加快了首屏加载时间。
          • SSR占用更多的CPU和内存资源
          • 一些常用的浏览器API可能无法正常使用
          • 在vue中只支持beforeCreate和created两个生命周期

          一.开始vue-ssr之旅

          yarn add vue-server-renderer vue yarn add koa koa-router

          createRenderer,创建一个渲染函数 renderToString, 渲染出一个字符串

          const Vue = require('vue'); const render = require('vue-server-renderer'); const Koa = require('koa'); const Router = require('koa-router'); const app = new Koa(); const router = new Router(); const vm = new Vue({ data(){ return {msg:"hello world"} }, template:`<div>{{msg}}</div>` }); router.get('/',async (ctx)=>{ let r = await render.createRenderer().renderToString(vm); ctx.body = ` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> ${r} </body> </html> ` }); app.use(router.routes()); app.listen(4000);

          二.采用模板渲染

          <!DOCTYPE html> <html lang="en"> <head><title>Hello</title></head> <body> <!--vue-ssr-outlet--> </body> </html>

          传入template 替换掉注释标签

          const Vue = require('vue'); const render = require('vue-server-renderer'); const Koa = require('koa'); const Router = require('koa-router'); const app = new Koa(); const router = new Router(); const vm = new Vue({ data(){ return {msg:"hello world"} }, template:`<div>{{msg}}</div>` }); const template = require('fs').readFileSync('./index.html','utf8'); router.get('/',async (ctx)=>{ let r = await render.createRenderer({ template }).renderToString(vm); ctx.body = r; }); app.use(router.routes()); app.listen(4000);

          三.ssr目录创建

          ├── config │ ├── webpack.base.js │ ├── webpack.client.js │ └── webpack.server.js ├── dist │ ├── client.bundle.js │ ├── index.html │ ├── index.ssr.html │ ├── server.bundle.js │ ├── vue-ssr-client-manifest.json │ └── vue-ssr-server-bundle.json ├── package.json ├── public │ ├── index.html │ └── index.ssr.html ├── server.js ├── src │ ├── App.vue │ ├── components │ │ ├── Bar.vue │ │ └── Foo.vue │ ├── entry-client.js │ ├── entry-server.js │ ├── app.js │ ├── router.js │ └── store.js ├── webpack.config.js

          四.通过webpack实现编译vue项目

          安装插件

          yarn add webpack webpack-cli webpack-dev-server vue-loader vue-style-loader css-loader html-webpack-plugin @babel/core @babel/preset-env babel-loader vue-template-compiler webpack-merge

          const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const VueLoaderPlugin = require('vue-loader/lib/plugin') const resolve = (dir)=>{ return path.resolve(__dirname,dir) } module.exports = { entry: resolve('./src/client-entry.js'), output:{ filename:'[name].bundle.js', path:resolve('dist') }, module:{ rules:[ { test:/.css$/, use:['vue-style-loader','css-loader'] }, { test:/.js$/, use:{ loader:'babel-loader', options:{ presets:['@babel/preset-env'] } }, exclude:/node_modules/ }, { test:/.vue$/, use:'vue-loader' } ] }, plugins:[ new VueLoaderPlugin(), new HtmlWebpackPlugin({ template:'./index.html' }) ] }

          app.js

          import Vue from "vue"; import App from "./App.vue"; export default () => { // 为了保证实例的唯一性所以导出一个创建实例的函数 const app = new Vue({ render: h => h(App) }); return { app }; };

          client-entry.js

          import createApp from "./app"; const { app } = createApp(); app.$mount("#app"); // 客户端渲染手动挂载到dom元素上

          server-entry.js

          import createApp from "./app"; export default () => { const { app } = createApp(); return app; // 服务端渲染只需将渲染的实例导出即可 };

          五.配置客户端打包和服务端打包

          • webpack.base.js

          let path = require('path'); let VueLoaderPlugin = require('vue-loader/lib/plugin') module.exports = { output:{ filename:'[name].bundle.js', path:path.resolve(__dirname,'../dist') }, module:{ rules:[ {test:/.css/,use:['vue-style-loader','css-loader']}, { test:/.js/, use:{ loader:'babel-loader', options:{ presets:['@babel/preset-env'] }, }, exclude:/node_modules/, }, {test:/.vue/,use:'vue-loader'} ] }, plugins:[ new VueLoaderPlugin() ] }

          • webpack.client.js

          const merge = require("webpack-merge"); const path = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const base = require("./webpack.base"); const resolve = filepath => { return path.resolve(__dirname, filepath); }; module.exports = merge(base, { entry: { client: resolve("../src/client-entry.js") }, plugins: [ new HtmlWebpackPlugin({ template: resolve("../template/index.client.html") }) ] });

          • webpack.server.js

          const merge = require("webpack-merge"); const path = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const base = require("./webpack.base"); const resolve = filepath => { return path.resolve(__dirname, filepath); }; module.exports = merge(base, { entry: { server: resolve("../src/server-entry.js") }, target: "node", output: { libraryTarget: "commonjs2" // 导出供服务端渲染来使用 }, plugins: [ new HtmlWebpackPlugin({ filename: "index.ssr.html", template: resolve("../template/index.ssr.html"), excludeChunks: ["server"] }) ] });

          六.配置运行脚本

          "scripts": { "client:dev": "webpack-dev-server --config ./build/webpack.client.js", // 客户端开发环境 "client:build": "webpack --config ./build/webpack.client.js", // 客户端打包环境 "server:build": "webpack --config ./build/webpack.server.js" // 服务端打包环境 },

          七.服务端配置

          在App.vue上增加id="app"可以保证元素被正常激活

          const Koa = require("koa"); const Router = require("koa-router"); const static = require("koa-static"); const path = require("path"); const app = new Koa(); const router = new Router(); const VueServerRenderer = require("vue-server-renderer"); const fs = require("fs"); // 服务端打包的结果 const serverBundle = fs.readFileSync("./dist/server.bundle.js", "utf8"); const template = fs.readFileSync("./dist/index.ssr.html", "utf8"); const render = VueServerRenderer.createBundleRenderer(serverBundle, { template }); router.get("/", async ctx => { ctx.body = await new Promise((resolve, reject) => { render.renderToString((err, html) => { // 必须写成回调函数的方式否则样式不生效 resolve(html); }); }); }); app.use(router.routes()); app.use(static(path.resolve(__dirname, "dist"))); app.listen(3000);

          在index.ssr.html中需要手动引入客户端打包后的结果

          七.通过json配置createBundleRenderer方法

          实现热更新,自动增加preload和prefetch,以及可以使用sourceMap

          const VueSSRClientPlugin = require('vue-server-renderer/client-plugin'); // 在客户端打包时增加插件 const VueSSRServerPlugin = require('vue-server-renderer/server-plugin'); // 在服务端打包时增加插件 const Koa = require("koa"); const Router = require("koa-router"); const static = require("koa-static"); const path = require("path"); const app = new Koa(); const router = new Router(); const VueServerRenderer = require("vue-server-renderer"); const fs = require("fs"); // 服务端打包的结果 // const serverBundle = fs.readFileSync("./dist/server.bundle.js", "utf8"); const template = fs.readFileSync("./dist/index.ssr.html", "utf8"); const serverBundle = require("./dist/vue-ssr-server-bundle.json"); const clientManifest = require("./dist/vue-ssr-client-manifest.json"); const render = VueServerRenderer.createBundleRenderer(serverBundle, { template, clientManifest // 自动注入客户端打包后的文件 }); router.get("/", async ctx => { ctx.body = await new Promise((resolve, reject) => { render.renderToString((err, html) => { // 必须写成回调函数的方式否则样式不生效 resolve(html); }); }); }); app.use(router.routes()); app.use(static(path.resolve(__dirname, "dist"))); app.listen(3000);

          Vue服务端渲染SSR示例如何改写为长尾关键词?

          八.集成VueRouter

          yarn add vue-router

          import Vue from "vue"; import VueRouter from "vue-router"; import Foo from "./components/Foo.vue"; Vue.use(VueRouter); export default () => { const router = new VueRouter({ mode: "history", routes: [ { path: "/", component: Foo }, { path: "/bar", component: () => import("./components/Bar.vue") } ] }); return router; };

          导出路由配置

          配置入口文件

          import Vue from "vue"; import App from "./App.vue"; import createRouter from "./router"; export default () => { const router = createRouter(); const app = new Vue({ router, render: h => h(App) }); return { app, router }; };

          配置组件信息

          <template> <div id="app"> <router-link to="/"> foo</router-link> <router-link to="/bar"> bar</router-link> <router-view></router-view> </div> </template>

          防止刷新页面不存在

          router.get("*", async ctx => { ctx.body = await new Promise((resolve, reject) => { render.renderToString({ url: ctx.url }, (err, html) => { // 必须写成回调函数的方式否则样式不生效 resolve(html); }); }); });

          保证异步路由加载完成

          export default ({ url }) => { return new Promise((resolve, reject) => { const { app, router } = createApp(); router.push(url); router.onReady(() => { const matchComponents = router.getMatchedComponents(); if (!matchComponents.length) { return reject({ code: 404 }); } resolve(app); }, reject); }); }; // 服务器可以监控到错误信息,返回404 render.renderToString({ url: ctx.url }, (err, html) => { // 必须写成回调函数的方式否则样式不生效 if (err && err.code == 404) { resolve("404 Not Found"); } resolve(html); });

          十.集成vuex配置

          yarn add vuex

          import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); export default ()=>{ let store = new Vuex.Store({ state:{ username:'song' }, mutations:{ changeName(state){ state.username = 'hello'; } }, actions:{ changeName({commit}){ return new Promise((resolve,reject)=>{ setTimeout(() => { commit('changeName'); resolve(); }, 1000); }) } } }); return store }

          // 引用vuex import createRouter from './router'; import createStore from './store' export default ()=>{ let router = createRouter(); let store = createStore(); let app = new Vue({ router, store, render:(h)=>h(App) }) return {app,router,store} }

          在后端更新vuex

          import createApp from './main'; export default (context)=>{ return new Promise((resolve)=>{ let {app,router,store} = createApp(); router.push(context.url); // 默认访问到/a就跳转到/a router.onReady(()=>{ let matchComponents = router.getMatchedComponents(); // 获取路由匹配到的组件 Promise.all(matchComponents.map(component=>{ if(component.asyncData){ return component.asyncData(store); } })).then(()=>{ context.state = store.state; // 将store挂载在window.__INITIAL_STATE__ resolve(app); }); }) }) }

          在浏览器运行时替换store

          // 在浏览器运行代码 if(typeof window !== 'undefined' && window.__INITIAL_STATE__){ store.replaceState(window.__INITIAL_STATE__); }

          需要执行的钩子函数

          export default { mounted() { return this.$store.dispatch("changeName"); }, asyncData(store) { return store.dispatch("changeName"); } };

          以上就是Vue 服务端渲染SSR示例详解的详细内容,更多关于Vue 服务端渲染SSR的资料请关注易盾网络其它相关文章!

          本文共计2270个文字,预计阅读时间需要10分钟。

          Vue服务端渲染SSR示例如何改写为长尾关键词?

          目录+手写Vue服务端渲染+一.开始vue-ssr之旅+二.采用模板渲染+三.ssr目录创建+四.通过webpack实现Vue项目编译+app.js+client-entry.js+server-entry.js+五.配置客户端打包和服务端打包+六.配置运行脚本

          目录
          • 手写Vue服务端渲染
          • 一.开始vue-ssr之旅
          • 二.采用模板渲染
          • 三.ssr目录创建
          • 四.通过webpack实现编译vue项目
            • app.js
            • client-entry.js
            • server-entry.js
          • 五.配置客户端打包和服务端打包
            • 六.配置运行脚本
              • 七.服务端配置
                • 七.通过json配置createBundleRenderer方法
                  • 八.集成VueRouter
                    • 配置入口文件
                    • 配置组件信息
                    • 防止刷新页面不存在
                    • 保证异步路由加载完成
                  • 十.集成vuex配置
                    • 在后端更新vuex
                    • 在浏览器运行时替换store
                    • 需要执行的钩子函数

                  手写Vue服务端渲染

                  概念:放在浏览器进行就是浏览器渲染,放在服务器进行就是服务器渲染。

                  • 客户端渲染不利于 SEO 搜索引擎优化
                  • 服务端渲染是可以被爬虫抓取到的,客户端异步渲染是很难被爬虫抓取到的
                  • SSR直接将HTML字符串传递给浏览器。大大加快了首屏加载时间。
                  • SSR占用更多的CPU和内存资源
                  • 一些常用的浏览器API可能无法正常使用
                  • 在vue中只支持beforeCreate和created两个生命周期

                  一.开始vue-ssr之旅

                  yarn add vue-server-renderer vue yarn add koa koa-router

                  createRenderer,创建一个渲染函数 renderToString, 渲染出一个字符串

                  const Vue = require('vue'); const render = require('vue-server-renderer'); const Koa = require('koa'); const Router = require('koa-router'); const app = new Koa(); const router = new Router(); const vm = new Vue({ data(){ return {msg:"hello world"} }, template:`<div>{{msg}}</div>` }); router.get('/',async (ctx)=>{ let r = await render.createRenderer().renderToString(vm); ctx.body = ` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> ${r} </body> </html> ` }); app.use(router.routes()); app.listen(4000);

                  二.采用模板渲染

                  <!DOCTYPE html> <html lang="en"> <head><title>Hello</title></head> <body> <!--vue-ssr-outlet--> </body> </html>

                  传入template 替换掉注释标签

                  const Vue = require('vue'); const render = require('vue-server-renderer'); const Koa = require('koa'); const Router = require('koa-router'); const app = new Koa(); const router = new Router(); const vm = new Vue({ data(){ return {msg:"hello world"} }, template:`<div>{{msg}}</div>` }); const template = require('fs').readFileSync('./index.html','utf8'); router.get('/',async (ctx)=>{ let r = await render.createRenderer({ template }).renderToString(vm); ctx.body = r; }); app.use(router.routes()); app.listen(4000);

                  三.ssr目录创建

                  ├── config │ ├── webpack.base.js │ ├── webpack.client.js │ └── webpack.server.js ├── dist │ ├── client.bundle.js │ ├── index.html │ ├── index.ssr.html │ ├── server.bundle.js │ ├── vue-ssr-client-manifest.json │ └── vue-ssr-server-bundle.json ├── package.json ├── public │ ├── index.html │ └── index.ssr.html ├── server.js ├── src │ ├── App.vue │ ├── components │ │ ├── Bar.vue │ │ └── Foo.vue │ ├── entry-client.js │ ├── entry-server.js │ ├── app.js │ ├── router.js │ └── store.js ├── webpack.config.js

                  四.通过webpack实现编译vue项目

                  安装插件

                  yarn add webpack webpack-cli webpack-dev-server vue-loader vue-style-loader css-loader html-webpack-plugin @babel/core @babel/preset-env babel-loader vue-template-compiler webpack-merge

                  const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const VueLoaderPlugin = require('vue-loader/lib/plugin') const resolve = (dir)=>{ return path.resolve(__dirname,dir) } module.exports = { entry: resolve('./src/client-entry.js'), output:{ filename:'[name].bundle.js', path:resolve('dist') }, module:{ rules:[ { test:/.css$/, use:['vue-style-loader','css-loader'] }, { test:/.js$/, use:{ loader:'babel-loader', options:{ presets:['@babel/preset-env'] } }, exclude:/node_modules/ }, { test:/.vue$/, use:'vue-loader' } ] }, plugins:[ new VueLoaderPlugin(), new HtmlWebpackPlugin({ template:'./index.html' }) ] }

                  app.js

                  import Vue from "vue"; import App from "./App.vue"; export default () => { // 为了保证实例的唯一性所以导出一个创建实例的函数 const app = new Vue({ render: h => h(App) }); return { app }; };

                  client-entry.js

                  import createApp from "./app"; const { app } = createApp(); app.$mount("#app"); // 客户端渲染手动挂载到dom元素上

                  server-entry.js

                  import createApp from "./app"; export default () => { const { app } = createApp(); return app; // 服务端渲染只需将渲染的实例导出即可 };

                  五.配置客户端打包和服务端打包

                  • webpack.base.js

                  let path = require('path'); let VueLoaderPlugin = require('vue-loader/lib/plugin') module.exports = { output:{ filename:'[name].bundle.js', path:path.resolve(__dirname,'../dist') }, module:{ rules:[ {test:/.css/,use:['vue-style-loader','css-loader']}, { test:/.js/, use:{ loader:'babel-loader', options:{ presets:['@babel/preset-env'] }, }, exclude:/node_modules/, }, {test:/.vue/,use:'vue-loader'} ] }, plugins:[ new VueLoaderPlugin() ] }

                  • webpack.client.js

                  const merge = require("webpack-merge"); const path = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const base = require("./webpack.base"); const resolve = filepath => { return path.resolve(__dirname, filepath); }; module.exports = merge(base, { entry: { client: resolve("../src/client-entry.js") }, plugins: [ new HtmlWebpackPlugin({ template: resolve("../template/index.client.html") }) ] });

                  • webpack.server.js

                  const merge = require("webpack-merge"); const path = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const base = require("./webpack.base"); const resolve = filepath => { return path.resolve(__dirname, filepath); }; module.exports = merge(base, { entry: { server: resolve("../src/server-entry.js") }, target: "node", output: { libraryTarget: "commonjs2" // 导出供服务端渲染来使用 }, plugins: [ new HtmlWebpackPlugin({ filename: "index.ssr.html", template: resolve("../template/index.ssr.html"), excludeChunks: ["server"] }) ] });

                  六.配置运行脚本

                  "scripts": { "client:dev": "webpack-dev-server --config ./build/webpack.client.js", // 客户端开发环境 "client:build": "webpack --config ./build/webpack.client.js", // 客户端打包环境 "server:build": "webpack --config ./build/webpack.server.js" // 服务端打包环境 },

                  七.服务端配置

                  在App.vue上增加id="app"可以保证元素被正常激活

                  const Koa = require("koa"); const Router = require("koa-router"); const static = require("koa-static"); const path = require("path"); const app = new Koa(); const router = new Router(); const VueServerRenderer = require("vue-server-renderer"); const fs = require("fs"); // 服务端打包的结果 const serverBundle = fs.readFileSync("./dist/server.bundle.js", "utf8"); const template = fs.readFileSync("./dist/index.ssr.html", "utf8"); const render = VueServerRenderer.createBundleRenderer(serverBundle, { template }); router.get("/", async ctx => { ctx.body = await new Promise((resolve, reject) => { render.renderToString((err, html) => { // 必须写成回调函数的方式否则样式不生效 resolve(html); }); }); }); app.use(router.routes()); app.use(static(path.resolve(__dirname, "dist"))); app.listen(3000);

                  在index.ssr.html中需要手动引入客户端打包后的结果

                  七.通过json配置createBundleRenderer方法

                  实现热更新,自动增加preload和prefetch,以及可以使用sourceMap

                  const VueSSRClientPlugin = require('vue-server-renderer/client-plugin'); // 在客户端打包时增加插件 const VueSSRServerPlugin = require('vue-server-renderer/server-plugin'); // 在服务端打包时增加插件 const Koa = require("koa"); const Router = require("koa-router"); const static = require("koa-static"); const path = require("path"); const app = new Koa(); const router = new Router(); const VueServerRenderer = require("vue-server-renderer"); const fs = require("fs"); // 服务端打包的结果 // const serverBundle = fs.readFileSync("./dist/server.bundle.js", "utf8"); const template = fs.readFileSync("./dist/index.ssr.html", "utf8"); const serverBundle = require("./dist/vue-ssr-server-bundle.json"); const clientManifest = require("./dist/vue-ssr-client-manifest.json"); const render = VueServerRenderer.createBundleRenderer(serverBundle, { template, clientManifest // 自动注入客户端打包后的文件 }); router.get("/", async ctx => { ctx.body = await new Promise((resolve, reject) => { render.renderToString((err, html) => { // 必须写成回调函数的方式否则样式不生效 resolve(html); }); }); }); app.use(router.routes()); app.use(static(path.resolve(__dirname, "dist"))); app.listen(3000);

                  Vue服务端渲染SSR示例如何改写为长尾关键词?

                  八.集成VueRouter

                  yarn add vue-router

                  import Vue from "vue"; import VueRouter from "vue-router"; import Foo from "./components/Foo.vue"; Vue.use(VueRouter); export default () => { const router = new VueRouter({ mode: "history", routes: [ { path: "/", component: Foo }, { path: "/bar", component: () => import("./components/Bar.vue") } ] }); return router; };

                  导出路由配置

                  配置入口文件

                  import Vue from "vue"; import App from "./App.vue"; import createRouter from "./router"; export default () => { const router = createRouter(); const app = new Vue({ router, render: h => h(App) }); return { app, router }; };

                  配置组件信息

                  <template> <div id="app"> <router-link to="/"> foo</router-link> <router-link to="/bar"> bar</router-link> <router-view></router-view> </div> </template>

                  防止刷新页面不存在

                  router.get("*", async ctx => { ctx.body = await new Promise((resolve, reject) => { render.renderToString({ url: ctx.url }, (err, html) => { // 必须写成回调函数的方式否则样式不生效 resolve(html); }); }); });

                  保证异步路由加载完成

                  export default ({ url }) => { return new Promise((resolve, reject) => { const { app, router } = createApp(); router.push(url); router.onReady(() => { const matchComponents = router.getMatchedComponents(); if (!matchComponents.length) { return reject({ code: 404 }); } resolve(app); }, reject); }); }; // 服务器可以监控到错误信息,返回404 render.renderToString({ url: ctx.url }, (err, html) => { // 必须写成回调函数的方式否则样式不生效 if (err && err.code == 404) { resolve("404 Not Found"); } resolve(html); });

                  十.集成vuex配置

                  yarn add vuex

                  import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); export default ()=>{ let store = new Vuex.Store({ state:{ username:'song' }, mutations:{ changeName(state){ state.username = 'hello'; } }, actions:{ changeName({commit}){ return new Promise((resolve,reject)=>{ setTimeout(() => { commit('changeName'); resolve(); }, 1000); }) } } }); return store }

                  // 引用vuex import createRouter from './router'; import createStore from './store' export default ()=>{ let router = createRouter(); let store = createStore(); let app = new Vue({ router, store, render:(h)=>h(App) }) return {app,router,store} }

                  在后端更新vuex

                  import createApp from './main'; export default (context)=>{ return new Promise((resolve)=>{ let {app,router,store} = createApp(); router.push(context.url); // 默认访问到/a就跳转到/a router.onReady(()=>{ let matchComponents = router.getMatchedComponents(); // 获取路由匹配到的组件 Promise.all(matchComponents.map(component=>{ if(component.asyncData){ return component.asyncData(store); } })).then(()=>{ context.state = store.state; // 将store挂载在window.__INITIAL_STATE__ resolve(app); }); }) }) }

                  在浏览器运行时替换store

                  // 在浏览器运行代码 if(typeof window !== 'undefined' && window.__INITIAL_STATE__){ store.replaceState(window.__INITIAL_STATE__); }

                  需要执行的钩子函数

                  export default { mounted() { return this.$store.dispatch("changeName"); }, asyncData(store) { return store.dispatch("changeName"); } };

                  以上就是Vue 服务端渲染SSR示例详解的详细内容,更多关于Vue 服务端渲染SSR的资料请关注易盾网络其它相关文章!