背景
简单说一下需求,一个页面中只存在一个Editor组件,但是需要通过选择不同类型展示不同的content的数据,不过直接通过提供的Editor组件加载的时候,在数据量大(测试数据226KB)的情况下, 切换类型时,加载数据会让页面直接卡死,好一会才会执行完毕。
下图展示了数据的大小:
目的
需要在切换不同的类型之后,editor组件丝滑的展示当前类型下的内容,
效果如下
数据量大-editor组件加载
技术栈
- vue2.x
- @wangEditor/eidtor @5.1.*
解决方案
思路来源:在官网看到了类似大文件10W字的案例,但是该案例只是单纯展示了页面初始化展示一次,针对加上切换逻辑,还是需要单独处理
核心代码:
import { createEditor } from "@wangeditor/editor";
createEditor({
selector: "#editor-id",
html: this.currentData.content,
config: {
readOnly: true,
},
});
使用官方提供的这种加载方式,实现了大数据量加载的问题。
切换之后如何动态丝滑更新?
- 第一步 ,我们需要监听使content数据变化的值,然后重新销毁
watch: {
activeIndex: {
handler() {
this.changeEditorContent();
},
immediate: false,
},
lang: {
handler() {
this.changeEditorContent();
},
immediate: false,
},
},
methods: {
changeEditorContent() {
this.editorLoading = true;
const editor = this.editor;
if (editor == null) {
this.editorLoading = false;
return;
}
editor.destroy(); // 组件销毁时,及时销毁编辑器
},
}
- 第二步,异步加载我们的editor数据
methods: {
changeEditorContent() {
const editor = this.editor;
if (editor == null) {
return;
}
editor.destroy();
// 异步加载
setTimeout(() => {
this.handleCreateEditor();
}, 300);
},
}
- 第三步,加上过渡loading效果
changeEditorContent() {
this.editorLoading = true;
const editor = this.editor;
if (editor == null) {
// 处理初次加载的问题
this.editorLoading = false;
return;
}
editor.destroy(); // 组件销毁时,及时销毁编辑器
setTimeout(() => {
this.handleCreateEditor();
}, 300);
},
/** nothing */
noop(e) {
return { e }
},
handleCreateEditor() {
try {
this.editor = createEditor({
selector: "#editorRef-article-record",
html: this.currentData.content,
config: {
readOnly: true,
onCreated: () => {
this.editorLoading = false;
},
},
});
} catch (err) {
// 这里处理掉wangeditor内部的create editor报错,
// 不影响执行 异步创建会产生
this.noop(err)
}
},
完整代码
<!--
* 修订记录
*
* @Author: grayson<grayson.gao@bvox.com>
* @Date: 2024-10-14 17:14:39
*
* Copyright © 2019-2024 bvox.com. All Rights Reserved.
-->
<template>
<div>
<Spin v-show="editorLoading" />
<div id="editor-id"></div>
</div>
</template>
<script>
import { createEditor } from "@wangeditor/editor";
export default {
watch: {
activeIndex: {
handler() {
this.changeEditorContent();
},
immediate: false,
},
lang: {
handler() {
this.changeEditorContent();
},
immediate: false,
},
},
beforeDestroy() {
const editor = this.editor;
if (editor == null) return;
editor.destroy(); // 组件销毁时,及时销毁编辑器
},
data() {
return {
lang: "",
activeIndex: 0,
editorLoading: false,
editor: null,
};
},
methods: {
changeEditorContent() {
this.editorLoading = true;
const editor = this.editor;
if (editor == null) {
this.editorLoading = false;
return;
}
editor.destroy(); // 组件销毁时,及时销毁编辑器
setTimeout(() => {
this.handleCreateEditor();
}, 300);
},
/** nothing */
noop(e) {
return { e }
},
handleCreateEditor() {
try {
this.editor = createEditor({
selector: "#editorRef-article-record",
html: this.currentData.content,
config: {
readOnly: true,
onCreated: () => {
this.editorLoading = false;
},
},
});
} catch (err) {
this.noop(err)
}
},
},
};
</script>
最后
按照以上的处理,我们就可以得到开头所说的,丝滑的打开不同类型下的内容。
不同情况下,大家可能需要做不一样的调整,但是核心代码是不会动的,再次验证方案永远都是只有最合适的,没有最好的!
如果帮到了大家,记得给博主点个赞!