Vue SSR 组件加载问题


Posted in Javascript onMay 02, 2018

Node 端渲染提示 window/document 没有定义

Vue SSR 组件加载问题

业务场景

首先来看一个简单的 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     https:// github.com/hubcarl/easy    webpack   内置的全局 Webpack 常量 EASY_ENV_IS_BROWSER  http:// hubcarl.github.io/easyw ebpack/webpack/env   进行 判断。 这样在构建压缩期间, 如果是 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 挂载组件, 从而达到解决服务端渲染报错的问题

https:// github.com/hubcarl/egg- vue-webpack-boilerplate/blob/master/app/web/page/dynamic/dynamic.vue

总结

以上所述是小编给大家介绍的Vue SSR 组件加载问题,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
DHTML Slide Show script图片轮换
Mar 03 Javascript
JQuery 绑定select标签的onchange事件,弹出选择的值,并实现跳转、传参
Jan 06 Javascript
Jquery操作下拉框(DropDownList)实现取值赋值
Aug 13 Javascript
更快的异步执行(setTimeout多浏览器)
Aug 12 Javascript
jQuery后代选择器用法实例
Dec 23 Javascript
js实现仿Discuz文本框弹出层效果
Aug 13 Javascript
使用Javascript实现选择下拉菜单互移并排序
Feb 23 Javascript
jquery动态创建div与input的实例代码
Oct 12 Javascript
javascript简写常用的12个技巧(可以大大减少你的js代码量)
Mar 28 Javascript
用jquery获取select标签中选中的option值及文本的示例
Jan 25 jQuery
vue实现文字横向无缝走马灯组件效果的实例代码
Apr 09 Javascript
通过vue手动封装on、emit、off的代码详解
May 29 Javascript
基于jquery实现左右上下移动效果
May 02 #jQuery
关于Vue在ie10下空白页的debug小结
May 02 #Javascript
解析Json字符串的三种方法日常常用
May 02 #Javascript
使用vue-cli创建项目的图文教程(新手入门篇)
May 02 #Javascript
vue中的模态对话框组件实现过程
May 01 #Javascript
vue如何通过id从列表页跳转到对应的详情页
May 01 #Javascript
使用Vue的slot插槽分发父组件内容实现高度复用、更加灵活的组件(推荐)
May 01 #Javascript
You might like
PHP中常见的缓存技术实例分析
2015/09/23 PHP
浅谈PHP面向对象之访问者模式+组合模式
2017/05/22 PHP
javascript 动态添加表格行
2006/06/22 Javascript
js 鼠标拖动对象 可让任何div实现拖动效果
2009/11/09 Javascript
javascript打印输出json实例
2013/11/11 Javascript
javascript 上下banner替换具体实现
2013/11/14 Javascript
js保留小数点后几位的写法
2014/01/03 Javascript
关于页面嵌入swf覆盖div层的问题的解决方法
2014/02/11 Javascript
javascript实现回到顶部特效
2015/05/06 Javascript
JavaScript制作淘宝星级评分效果的思路
2020/06/23 Javascript
js实现简单计算器
2015/11/22 Javascript
javascript实现随机显示星星特效
2016/01/28 Javascript
使用getBoundingClientRect方法实现简洁的sticky组件的方法
2016/03/22 Javascript
jquery zTree异步加载、模糊搜索简单实例分享
2016/03/24 Javascript
JavaScript简单下拉菜单特效
2016/09/13 Javascript
AngularJS 模块化详解及实例代码
2016/09/14 Javascript
vue2实现数据请求显示loading图
2017/11/28 Javascript
vue-cli安装使用流程步骤详解
2018/11/08 Javascript
Vant的安装和配合引入Vue.js项目里的方法步骤
2018/12/05 Javascript
JavaScript静态作用域和动态作用域实例详解
2019/06/17 Javascript
jQuery实现鼠标移入显示蒙版效果
2020/01/11 jQuery
Python实现从log日志中提取ip的方法【正则提取】
2018/03/31 Python
在Python中分别打印列表中的每一个元素方法
2018/11/07 Python
对python 通过ssh访问数据库的实例详解
2019/02/19 Python
如何用Python编写一个电子考勤系统
2021/02/08 Python
优衣库美国官网:UNIQLO美国
2018/04/14 全球购物
Currentbody美国/加拿大:美容仪专家
2020/03/09 全球购物
2014年大学生自我评价
2014/01/19 职场文书
就业协议书样本
2014/08/20 职场文书
试用期辞职信范文
2015/03/02 职场文书
推荐信范文大全
2015/03/27 职场文书
2015年小学数学教师工作总结
2015/05/20 职场文书
毕业论文答辩开场白和结束语
2015/05/27 职场文书
班干部竞选演讲稿(精选5篇)
2019/09/24 职场文书
Vue-Element-Admin集成自己的接口实现登录跳转
2021/06/23 Vue.js
vue+element ui实现锚点定位
2021/06/29 Vue.js