在用nuxt开发服务端渲染项目并引入第三方库的时候,常常会遇到window或document未定义的状况,缘由是这个第三方库里面用到了window或者document,而后在服务端打包的时候,node环境并无window或者document,因此就报了window或document未定义的错误。css
并且,咱们在引入第三方库的时候,并不但愿把第三方库打包进app.js,而是但愿这个第三方库只在须要的页面才加载。html
下面以tinymce这个第三方库为例,记录我在nuxt.js框架中的实现方法,供之后开发时参考,相信对其余人也有用。vue
咱们不能把tinymce放到plugin里面去引入,由于这样会引入到全局js里面去。node
nuxt官网介绍了一种方法:Window 或 Document 对象未定义?,可是写的很简略,我这里详细说明一下。webpack
首先咱们在要引入的blog.vue文件中,经过判断是不是客户端来选择性的加载tinymce这个库:web
let tinymce; if (process.client) { tinymce = require('tinymce/tinymce'); // A theme is also required require('tinymce/themes/silver/theme'); // Any plugins you want to use has to be imported require('tinymce/plugins/advlist'); require('tinymce/plugins/wordcount'); require('tinymce/plugins/autolink'); require('tinymce/plugins/autosave'); require('tinymce/plugins/charmap'); require('tinymce/plugins/codesample'); require('tinymce/plugins/contextmenu'); require('tinymce/plugins/emoticons'); require('tinymce/plugins/fullscreen'); require('tinymce/plugins/hr'); require('tinymce/plugins/imagetools'); require('tinymce/plugins/insertdatetime'); require('tinymce/plugins/link'); require('tinymce/plugins/media'); require('tinymce/plugins/noneditable'); require('tinymce/plugins/paste'); require('tinymce/plugins/print'); require('tinymce/plugins/searchreplace'); require('tinymce/plugins/tabfocus'); require('tinymce/plugins/template'); require('tinymce/plugins/textpattern'); require('tinymce/plugins/visualblocks'); require('tinymce/plugins/anchor'); require('tinymce/plugins/autoresize'); require('tinymce/plugins/bbcode'); require('tinymce/plugins/code'); require('tinymce/plugins/colorpicker'); require('tinymce/plugins/directionality'); require('tinymce/plugins/fullpage'); require('tinymce/plugins/help'); require('tinymce/plugins/image'); require('tinymce/plugins/importcss'); require('tinymce/plugins/legacyoutput'); require('tinymce/plugins/lists'); require('tinymce/plugins/nonbreaking'); require('tinymce/plugins/pagebreak'); require('tinymce/plugins/preview'); require('tinymce/plugins/save'); require('tinymce/plugins/spellchecker'); require('tinymce/plugins/table'); require('tinymce/plugins/textcolor'); require('tinymce/plugins/toc'); require('tinymce/plugins/visualchars'); require('tinymce/skins/lightgray/skin.min.css'; }
这样,在服务端就不会引入这些库,只会在客户端引入。可是服务端没有引入的话,相关js在执行的时候会报不存在的错误,这里就须要再用process.client判断一下环境再执行。示例以下:app
if (process.client) { tinymce.init({ ...options, ...this.otherOptions, language: this.language, }); )
有时候咱们但愿用引入tinymce.js的方法来引入,而不用webpack打包的方式。这个时候咱们须要在blog.vue里面加上以下代码便可:框架
export default { name: 'Blog', layout: 'blank', head: { script: [ { src: '/tinymce.5.0.4/tinymce.min.js' }, ], }, }
其中上面src的路径是static文件夹的绝对路径。ui
按照上述的方法会有一个问题,就是执行下面的代码的时候,即便用了process.client,但仍是会报tinymce不存在的错误:this
if (process.client) { tinymce.init({ ...options, ...this.otherOptions, language: this.language, }); )
缘由是,客户端打包的时候,tinymce确实是没有定义的。因此这里改为以下形式便可:
if (process.client) { window.tinymce.init({ ...options, ...this.otherOptions, language: this.language, }); )
nuxt有一个组件是no-ssr组件,因此上面的html最好用no-ssr包起来,否则会报tinymce组件没有定义的错误:
<no-ssr placeholder="Loading..."> <tinymce id="myTinymce" v-model="content" :height="600" /> </no-ssr>