Vue SSR 组件加载问题
node 端渲染提示 window/document 没有定义
业务场景
首先来看一个简单的 vue 组件 test.vue
<template> <div> <h2>clientheight: {{ clientheight }} px </h2> </div> </template> <script type="text/babel"> export default { data(){ return { } }, computed :{ clientheight() { return document.body.clientheight; } }, mounted(){ } } </script>
上面 test.vue 组件通过 vue computed 属性 clientheight 直接获取 document 的文档高度,这段代码在前端渲染是不会报错的,也能拿到正确的值。但如果把这个组件放到 ssr(server side render) 模式下, 就会报如下错误:
referenceerror: document is not defined
解决方案
通过 typeof 判断是否是存在 document 对象, 如果存在则执行后面代码。 这种方式虽然能解决问题, 但在 webpack 构建压缩时, 不会执行的代码不会被剔除,也会打包到 js 文件中去, 因为这个是在运行期才知道结果的, 所以在 webpack 构建方案中,不建议使用 typeof 方式判断。而是使用 webpack 提供的 webpack.defineplugin 插件定义常量解决。
clientheight() { return typeof document === 'object' ? document.body.clientheight : ''; }
使用 webpack 提供的 webpack.defineplugin 插件定义常量解决。 这里直接使用 easywebpack webpack 内置的全局 webpack 常量 easy_env_is_browser 进行 判断。 这样在构建压缩期间, 如果是 node 模式构建, easy_env_is_browser 会被替换为 false,如果是 browser 模式构建, easy_env_is_browser 会被替换为 true,最后构建后代码也就是变成了 true 或者 false 的常量。 因为这个是构建期间执行的,压缩插件剔除永远不会被执行的代码, 也就是
dead_code clientheight() { return easy_env_is_browser ? document.body.clientheight : ''; }
npm vue 组件 ssr 支持
针对上面这种自己写的代码,我们可以通过这种方式解决,因为可以直接修改。但如果我们引入的一个 npm vue 插件想进行ssr渲染, 但这个插件里面使用了 window/docment 等浏览器对象, 并没有对 ssr 模式进行兼容,这个时候该如何解决呢?
一般我们通过 通过 v-if 来决定是否渲染该组件 和 vue 只在前端挂载组件解决问题 可以解决。
通过 v-if 来决定是否渲染该组件
<template> <div v-if="isbrowser"> <loading></loading> </div> </template> <script type="text/babel"> export default { componets:{ loading: () =>import('vue-loading'); } data(){ return { isbrowser: easy_env_is_browser } }, mounted(){ } } </script>
vue 只在前端挂载组件解决问题
<template> <div> <loading></loading> </div> </template> <script type="text/babel"> export default { data(){ return { } }, beforemount() { // 只会在浏览器执行 this.$options.components.loading = () =>import('vue-loading'); }, mounted(){ } } </script>
loading 组件因为没有注册, 在 ssr 模式, <loading></loading> 会被原样输出到 html 中,不会报错且不能被浏览器识别, 在显示时不会有内容。当 ssr 直出 html 后,浏览器模式中执行 beforemount 挂载组件, 从而达到解决服务端渲染报错的问题
总结
以上所述是小编给大家介绍的vue ssr 组件加载问题,希望对大家有所帮助