tinymce的官方vue组件是云托管,靠cdn来分发,依赖于外部网络,可靠性打了折扣。所以想下载到自己的服务器上自己托管,npm上的@packy-tang/vue-tinymce组件就可以达到这样的目的。但是这个组件需要在首页同步加载TinyMCE的脚本(tinymce.min.js),有388k左右,影响首页的加载速度,所以想改成异步加载后可以加快首页响应的速度。
直接改成<script src="./static/tinymce/tinymce.min.js" defer></script>是不行的,如果在异步加载期间使用了这个组件会出错。
要解决这个问题,首先想到的是在首页中异步加载tinymce.min.js,然后在mounted钩子中用await等待这个加载完成。实际测试发现await虽然可以阻塞mounted钩子,但是不能阻塞mounted后面的钩子导致后面的代码出错,也就是说vue生命周期钩子不支持await,每个钩子并不会等待上一个钩子执行完后才执行,它们之间的关系是顺序异步,一旦你阻塞这个钩子,那么下一个钩子就会执行,没有达到我们想阻塞的目的。
这个在网上找到了讨论和官方回答
Await async component lifecycle hooks · Issue #7209 · vuejs/vue · GitHub
既然vue生命周期钩子不支持await,就不要试图阻塞mounted,假装t组件已经渲染完成,通过脚本加载完的事件来事后延迟渲染组件,不需要长时间的延迟,只需要延迟几秒钟tinymce.min.js的加载就完成了。
异步加载脚本,加载完后发通知事件
export function loadTinymce(url) {
var js = document.createElement('script')
js.src = url
js.defer = true
js.onload = function() {
document.dispatchEvent(new Event('tinymce