记录一下Nuxt SSR中使用WangEditor的问题,这也体现JS原型在架构场景下的重要性。
前提须知:
Nuxt SPA 按照文档去使用WangEditor插件是没有问题的,因为页面渲染是在前端层面执行的;
Nuxt SSR 要区分前、后端两个时刻,后端渲染的时候是不能使用window对象的;
Nuxt 框架可以设置plugins只作用于前端(ssr:false);
在Nuxt SSR 也不能使用script src 的方式加载JS库;
可以利用导航守卫,相当于拦截器,每次页面路径变化都会自动触发相应的函数;
使用Nuxt SSR 作为项目框架其实也是为了SEO和前后端分离两者兼得;
近期Nuxt SSR项目需要使用富文本编辑器,因为习惯了WangEditor,所以就想把WangEditor集成到Nuxt SSR架构中,但过程中是各种崩溃,接下来是实验流程:
只要在Nuxt框架中使用都要先安装模块:
npm i wangeditor --save
按照WangEditor文档中的使用方式:
import E from 'wangeditor'const editor = new E('#div1')// 或者 const editor = new E( document.getElementById('div1') )editor.create()
这种方式在SPA模式下的Nuxt中使用是一切顺利,但是在SSR中必须崩,因为后端nodejs没有window对象,所以根本无法编译import 引入的前端插件;
各种上网找解决方案,都是vue-quill-editor集成的解决方案,使用方式上与ElementUI 集成方案一样:在插件中使用Vue.use()载入插件到Vue中,然后将插件配置到nuxt.config.js的plugins中,并且设置ssr:false:
import Vue from 'vue';import wangeditor from 'wangeditor';Vue.use(wangeditor);console.log("Vue:",Vue); //打印测试
结果还是崩,对比打印结果,发现ElementUI正常加入,打印结果出现ElementUI的常用标签,如下图:
wangeditor这边的结果如下图:
究其原因应该是WangEiditor中某些语法写得不规范,导致不被Vue.use()载入;
思来想去,其实不管是script src 还是 Vue.use( )原理都是将JS模块载入内存,然后在使用的地方实例化JS模块,就能正常使用了,而script src方式引入的库就相当于在window对象原型上加入模块变量,又想到导航守卫是可以设置只在前端执行,而且在页面跳转到达后都自动触发afterEach,于是可以这样( /plugins/weditor.js代码):
import E from "wangEditor"export default ({ app }) => { app.router.afterEach(() => { console.time(); //在Window原型中设置wangEditor Window.prototype.wangEditor = E; console.timeEnd(); });}
nuxt.config.js的plugins配置代码:
plugins: [ {src:'@/plugins/weditor',ssr:false} ],
页面上也只能在vue挂载完成后的mounted生命周期中实例化插件,因为在mounted之前的生命周期函数都不能使用window:
<template> <div> <h1>wangEditor编辑器的使用h1> <div id="div1"> <p> 欢迎使用 <b>wangEditorb> 富文本编辑器 p> div> div>template><script>export default { mounted: function() { console.log("wangEditor:", wangEditor); // var editor = new wangEditor("#div1"); // // 或者 const editor = new E( document.getElementById('div1') ) editor.create(); }};script><style>style>
最后完成:
总结:导航守卫中加入window原型是对每个页面都会有作用,就相当于在全局上内存上设置了插件模块,经过测试,页面加载可能会因此延迟0.03~0.05毫秒,其实可以忽略不计,如果不想每个页面都载入插件,其实是可以配置需要使用插件的页面路径配置,然后通过分支结构判断页面路径是否要把插件模块加入window原型的。
部分素材来源网络,如有侵权请联系删除