核心内容摘要
时光雕琢的韵味:50、60岁女性的俱乐部,优雅绽放的第二人生
初识服务器端渲染客户端渲染概述客户端渲染即传统的单页面应用SPA模式Vue.js 构建的应用程序默认情况下是一个 HTML 模板页面只有一个 id 为 app 的 div 根容器然后通过 webpack 打包生成 css、js 等资源文件浏览器加载、解析来渲染 HTML。
在客户端渲染时一般使用的是 webpack-dev-server 插件它可以帮助用户自动开启一个服务器端主要作用是监控代码并打包也可以配合 webpack-hot-middleware 来进行热更替HMR这样能提高开发效率。
服务器端渲染概述服务器端渲染就是将页面或者组件通过服务器生成 HTML 字符串将它们直接发送到浏览器最后将静态标记“混合”为客户端上完全交互的应用程序。
Vue 进行服务器端渲染时需要利用 Node.js 搭建一个服务器并添加服务器端渲染的代码逻辑。
服务器端渲染的优点利于 SEO。
首屏渲染速度快。
服务器端渲染的缺点服务器端压力增加。
涉及构建设置和部署的要求比较严格。
服务器端渲染的
注意事项Vue
2.
0 版本的服务器端渲染SSR要求 vue-server-renderer服务端渲染插件的版本要与 Vue 版本相匹配。
在使用 Vue-Router 路由插件时路由模式只能是 history 模式。
服务器端渲染的简单实现创建 vue-ssr 项目在项目存储目录下使用命令行工具创建一个 vue-ssr 项目。
示例创建 vue-ssr 项目终端执行# 创建文件夹 mkdir vue-ssr # 切换目录 cd vue-ssr # 初始化项目 npm init -y # 安装Vue和服务器端渲染的插件vue-server-renderer npm install vue
2.
16 vue-server-renderer
2.
16示例效果渲染 Vue 实例vue-server-renderer 安装完成后创建服务器脚本文件 test.js实现将 Vue 实例的渲染结果输出到控制台中。
示例渲染 Vue 实例服务器脚本文件test.js//
require导入Vue const Vue require(vue) //
创建一个Vue实例 const vm new Vue({ template: divSSR的简单使用/div }) //
导入vue-server-renderer并创建一个renderer实例 const renderer require(vue-server-renderer).createRenderer() //
将Vue实例渲染为HTML // 参数1要渲染的Vue实例对象 // 参数2回调箭头函数 // err渲染过程中的错误信息 // html渲染后的HTML代码 renderer.renderToString(vm, (err, html) { if (err) { throw err } console.log(html) })终端执行node test.js示例效果Express 搭建 SSRExpress 是一个基于 Node.js 平台的 Web 应用开发框架用来快速开发 Web 应用。
示例Express 搭建 SSR终端执行npm install express页面模板template.html!DOCTYPE html html langcn head meta charsetUTF-8 titleTitle/title /head body !-- 下面的注释不能删除也不能修改 这个注释是HTML占位符 -- !--vue-ssr-outlet-- /body /htmlExpress 配置文件express.js//
require导入Vue和Express const Vue require(vue) const express require(express) //
创建Express服务器 const serverexpress() //
借助fs文件读取工具读取页面模板 const renderer require(vue-server-renderer).createRenderer({ template: require(fs).readFileSync(./template.html, utf-
}) //
处理 GET 请求 // *所有请求都会进入该方法 // req请求对象 // res响应对象 server.get(*, (req, res) { res.set({Content-Type: text/html; charsetutf-8}) //
创建一个Vue实例 const vm new Vue({ data: { title: 当前位置, url: req.url }, template: div/div, }) //
将Vue实例渲染为HTML后输出 renderer.renderToString(vm, (err, html) { // end()结束响应并返回结果 if (err) { res.status(
.end(err: err) return } res.end(html) }) }) //
为Express监听8080端口 server.listen(8080, function () { console.log(server started at localhost:
})终端执行node express.js示例效果Koa 搭建 SSRKoa 是一个基于 Node.js 平台的 Web 开发框架致力于成为 Web 应用和 API 开发领域更富有表现力的技术框架。
Koa 能帮助开发者快速地编写服务器端应用程序通过 async 函数很好地处理异步的逻辑有力地增强错误处理。
示例Koa 搭建 SSR终端执行npm install koaKoa 配置文件koa.js//
require导入Vue和Koa const Vue require(vue) const Koa require(koa) //
创建Koa实例 const server new Koa() //
借助fs文件读取工具读取页面模板 const renderer require(vue-server-renderer).createRenderer({ template: require(fs).readFileSync(./template.html, utf-
}) //
添加一个中间件来处理所有请求 // async异步函数 // ctx上下文对象 // next将要处理的下一个函数 server.use(async (ctx, next) { //
创建一个 Vue 实例 const vm new Vue({ data: { title: 当前位置, url: ctx.url }, template: div/div }) //
将Vue实例渲染为HTML后输出 renderer.renderToString(vm, (err, html) { if (err) { ctx.res.status(
.end(err: err) return } ctx.body html }) }) //
为Koa监听8081端口 server.listen(8081, function () { console.log(server started at localhost:
})终端执行node koa.js示例效果webpack 搭建服务器端渲染基本流程webpack 服务器端渲染需要使用 entry-server.js 和 entry-client.js 两个入口文件两者通过打包生成两份 bundle 文件。
其中通过 entry-server.js 打包的代码是运行在服务器端而通过 entry-client.js 打包的代码运行在客户端。
webpack 服务器端渲染的流程项目搭建使用 webpack 可以实现服务器端渲染。
使用 webpack 可以实现服务器端渲染进入 Vue-CLI GUI创建 Vue-CLI 项目并添加 vue-router、koa、koa-static、vue-server-renderer、cross-env、lodash.merge、webpack-node-externals 依赖路由配置文件src/router/index.jsimport Vue from vue import VueRouter from vue-router Vue.use(VueRouter) // 将路由改造成工厂 // 确保每个请求时路由对象都是单例 export function createRouter() { const routes [ { path: /, name: home, component: () import(../views/HomeView.vue) }, { path: /about, name: about, component: () import(../views/AboutView.vue) } ] const router new VueRouter({ // 只能使用history模式 mode: history, routes }) return router }项目入口配置文件src/main.jsimport Vue from vue import App from ./App.vue import {createRouter} from ./router Vue.config.productionTip false export function createApp() { const router createRouter() const app new Vue({ router, render: h h(App) }) return {app, router} }服务端入口文件src/entry-server.jsimport { createApp } from ./main export default context { return new Promise((resolve, reject) { // 创建Vue实例和VueRouter路由对象 const { app, router } createApp() // 路由跳转 router.push(context.url) router.onReady(() { const matchedComponents router.getMatchedComponents() if (!matchedComponents.length) { return reject(new Error(no components matched)) } resolve(app) }, reject) }) }客户端入口文件src/entry-client.jsimport {createApp} from ./main.js; let {app,router} createApp(); router.onReady(() { app.$mount(#app); })Vue 项目配置文件vue.config.js// 加载相关插件 const VueSSRServerPlugin require(vue-server-renderer/server-plugin); const VueSSRClientPlugin require(vue-server-renderer/client-plugin); const nodeExternals require(webpack-node-externals); const merge require(lodash.merge); // 根据传入环境变量决定入口文件和相应配置项 // 分别生成server/client的文件 const TARGET_NODE process.env.WEBPACK_TARGET node; const target TARGET_NODE ? server : client; module.exports { configureWebpack: () ({ entry: ./src/entry-${target}.js, // 将entry指向应用程序的server/client文件 devtool: source-map, target: TARGET_NODE ? node : web, node: TARGET_NODE ? undefined : false, output: { libraryTarget: TARGET_NODE ? commonjs2 : undefined }, externals: TARGET_NODE ? nodeExternals({ allowlist: [/.css$/] }) : undefined, optimization: { splitChunks: undefined }, // 这是将服务器的整个输出构建为单个JSON文件的插件 // 服务端默认文件名为vue-ssr-server-bundle.json // 客户端默认文件名为vue-ssr-client-manifest.json plugins: [TARGET_NODE ? new VueSSRServerPlugin() : new VueSSRClientPlugin()] }), chainWebpack: config { config.module .rule(vue) .use(vue-loader) .tap(options { merge(options, { optimizeSSR: false }); }); if (TARGET_NODE) { config.plugins.delete(hmr); } } };npm 配置文件package.jsonscripts: { serve: vue-cli-service serve, build: vue-cli-service build, build:client: vue-cli-service build, build:server: cross-env WEBPACK_TARGETnode vue-cli-service build --mode server, build:ssr: npm run build:server npm run build:client },运行 build:ssr页面模板template.html!DOCTYPE html html langcn head meta charsetUTF-8 titleTitle/title /head body !--vue-ssr-outlet-- /body /htmlKoa 配置文件koa.jsconst Koa require(koa) const path require(path) const koaStatic require(koa-static) const server new Koa() const resolve file path.resolve(__dirname, file) // 开放dist文件夹 server.use(koaStatic(resolve(./dist))) const { createBundleRenderer } require(vue-server-renderer) const bundle require(./dist/vue-ssr-server-bundle.json) const clientManifest require(./dist/vue-ssr-client-manifest.json) // 渲染页面 const renderer createBundleRenderer(bundle, { runInNewContext: false, template: require(fs).readFileSync(resolve(./template.html), utf-
, clientManifest: clientManifest }); function renderToString(context) { return new Promise((resolve, reject) { renderer.renderToString(context, (err, html) { err ? reject(err) : resolve(html) }) }) } // 添加一个中间件来处理所有请求 server.use(async (ctx, next) { const context { title: ssr test, url: ctx.url } ctx.body await renderToString(context) }) server.listen(8081, function () { console.log(server started at localhost:
})终端执行node koa.js示例效果Nuxt.js 服务器端渲染框架创建 Nuxt.js 项目Nuxt.js 是一个基于 Vue.js 的轻量级应用框架可用来创建服务端渲染应用也可充当静态站点引擎生成静态站点应用具有优雅的代码结构分层和热加载等特性。
Nuxt.js 提供了利用 vue.js 开发服务端渲染的应用所需要的各种配置为了快速入门Nuxt.js 团队创建了脚手架工具 create-nuxt-app可以使用脚手架工具快速创建 Nuxt.js 项目。
示例创建 Nuxt.js 项目终端执行# 全局安装create-nuxt-app脚手架 npm install create-nuxt-app -g # 创建Nuxt.js项目 npx create-nuxt-app 项目名称示例效果终端执行# 切换目录 cd nuxtapp # 终端执行 npm run dev示例效果页面和路由在项目中pages 目录用来存放应用的路由及视图。
当直接访问根路径“/”的时候默认打开的是 index.vue 文件。
Nuxt.js 会根据目录结构自动生成对应的路由配置将请求路径和 pages 目录下的文件名映射。
比如访问“/test”就表示访问 test.vue 文件如果文件不存在就会提示 This page could not be found 错误。
pages 目录下的 vue 文件也可以放在子目录中在访问的时候也要加上子目录的路径。
页面跳转Nuxt.js 中使用 nuxt-link 组件来完成页面中路由的跳转类似于 Vue 中的路由组件 router-link它们具有相同的属性并且使用方式也相同。
Nuxt.js 中还可以使用编程式路由来完成页面中路由的跳转与 VueRouter 的使用方式一致。