简单封装富文本组件5.0-GWangEditor5
<!--
* @fileName: 富文本组件5.0-GWangEditor5.vue
* 继承大部分原生组件的树形和事件
* 支持图片、视频上传,官方文档地址:https://www.wangeditor.com/
* (v-html预览图片请使用Gvhtml.vue组件)
!-->
<template>
<a-spin :spinning="loading">
<div style="border: 1px solid #ccc;">
<Toolbar style="border-bottom: 1px solid #ccc"
:editor="editor"
:defaultConfig="toolbarConfig"
:mode="state.mode"
v-bind="$attrs" />
<Editor :style="{ height: height, overflowY: 'hidden' }"
v-model="state.html"
:defaultConfig="state.editorConfig"
:mode="state.mode"
v-bind="$attrs"
@onCreated="onCreated"
@onChange="onChange"
v-on="$listeners" />
</div>
</a-spin>
</template>
<script lang="ts">
import {
Component, Vue, Inject, Prop, Watch,
} from 'vue-property-decorator';
import {
Interp } from '@antv/x6';
import abpbase from 'geofly-framework-web-common/libs/abpbase';
import {
Editor, Toolbar } from '@wangeditor/editor-for-vue';
import {
IToolbarConfig, DomEditor } from '@wangeditor/editor';
import ChunkUploadRequest from 'geofly-framework-web-common/components/common/forms/impl/ChunkUploadRequest';
import number = Interp.number;
type InsertFnType = (url: string, poster: string) => void;
@Component({
name: 'GWangEditor',
components: {
Editor,
Toolbar,
},
})
export default class GWangEditor extends abpbase {
@Prop({
default: '' })
value: string
@Prop({
default: 'default' })
mode: string
@Prop({
type: Boolean, default: true })
enableUploadImg: boolean;
@Prop({
type: Number, default: -1 })
maxCharacterSize;
@Prop({
type: String, default: '500px' })
height;
@Prop({
type: Array, default: () => [] })
toolbarKeys;
@Prop({
type: Array, default: () => [] })
excludeKeys;
loading = false;
editor: any;
toolbarConfig = {
excludeKeys: [],
}
editorContent = '';
headers = {
};
token = `Bearer ${
window.abp.auth.getToken()}`;
state = {
html: '',
editorConfig: {
placeholder: '请输入内容...',
MENU_CONF: {
uploadImage: {
server: '/yg-system-api/file',
base64LimitSize: 1024 * 1024 * 2,
maxFileSize: 1024 * 1024 * 2,
allowedFileTypes: ['image/*'],
onBeforeUpload: (file: File) => {
console.log('file:', file);
return file;
},
},
uploadVideo: {
server: '/yg-system-api/file',
maxFileSize: 1024 * 1024 * 500,
headers: {
'content-type': 'multipart/form-data',
Authorization: this.token,
},
timeout: 60 * 1000 * 60,
onBeforeUpload: (file: File) => {
console.log('file:', file);
return file;
},
customUpload: (file: File, insertFn: InsertFnType) => {
this.customRequest(file, insertFn);
},
},
},
toolbarKeys: [],
excludeKeys: [],
},
mode: 'simple',
}
getEditor() {
return this.editor;
}
async customRequest(options, insertFn: InsertFnType) {
const config = {
headers: {
'content-type': 'multipart/form-data', ...this.headers },
};
this.loading = true;
const chunkUploadRequest = new ChunkUploadRequest();
chunkUploadRequest.uploadUrl = '/yg-system-api/file/chunk';
chunkUploadRequest.uploadConfig = config;
chunkUploadRequest.message = this.$message;
chunkUploadRequest.fileType = 0;
chunkUploadRequest.uploadChunks(options).then((res: any) => {
this.loading = false;
if (res.code == 0) {
const fileUrl = `/yg-system-api/file/file/${
res.result}?preview=1`;
const poster = '';
options.status = 'done';
this.$message.success('上传成功!');
insertFn(fileUrl, poster);
} else {
this.$message.error('上传失败!');
}
}, (err) => {
this.loading = false;
this.$message.error('上传失败!');
console.log('err:', err);
});
}
onCreated(editor) {
this.editor = Object.seal(editor);
}
onChange(editor) {
let html = null;
const isEmpty = editor.isEmpty();
if (!isEmpty) {
html = editor.getHtml();
}
this.$emit('change', html);
}
@Watch('value')
valueChanged(e) {
this.editorContent = this.getFinalString(e);
this.state.html = this.editorContent;
}
getFinalString(e): string {
return e && this.maxCharacterSize > 0 ? e.substring(0, this.maxCharacterSize) : e;
}
mounted() {
this.state.editorConfig.toolbarKeys = this.toolbarKeys;
this.state.editorConfig.excludeKeys = this.excludeKeys;
this.state.mode = this.mode;
}
beforeDestroy() {
const {
editor } = this;
if (editor == null) return;
editor.destroy();
}
}
</script>
<style src="@wangeditor/editor/dist/css/style.css"></style>
<style></style>