<template>
<div
class="editor"
v-loading="fullscreenLoading"
element-loading-text="正在上传至服务器...">
<Toolbar
style="border-bottom: 1px solid #ccc"
:editor="editorRef"
:defaultConfig="toolbarConfig"
mode="default" />
<Editor
v-model="valueHtml"
:defaultConfig="editorConfig"
mode="default"
@onCreated="handleCreated" />
</div>
</template>
<script setup lang="ts">
import { ElMessage } from 'element-plus';
import { uploadImage as uploadFileAndImage } from '@/api/tool';
import { debounce } from '@/utils/common';
import '@wangeditor/editor/dist/css/style.css'; // 引入 css
import { Editor, Toolbar } from '@wangeditor/editor-for-vue';
import { IEditorConfig, IToolbarConfig } from '@wangeditor/editor';
interface Props {
content: string;
}
const fullscreenLoading = ref<boolean>(false);
const props = withDefaults(defineProps<Props>(), {});
const editorRef = shallowRef(); // 编辑器实例,必须用 shallowRef
const valueHtml = ref(''); // 内容 HTML
const emits = defineEmits(['changeEditor']);
watch(
() => valueHtml.value,
debounce((newVal) => {
const text = editorRef.value.getText();
emits('changeEditor', newVal, text);
}, 400)
);
const toolbarConfig: Partial<IToolbarConfig> = {};
const editorConfig: Partial<IEditorConfig> = {
MENU_CONF: {
uploadImage: {
base64LimitSize: 20 * 1024, // 20kb
customUpload: async (file, insertFn) => {
let {
data: { msg, url }
} = await uploadFile(file, file.name);
if (!msg) return ElMessage.error('上传失败');
insertFn(url);
fullscreenLoading.value = false;
}
},
uploadVideo: {
customUpload: async (file, insertFn) => {
let {
data: { msg, url }
} = await uploadFile(file, file.name);
if (!msg) return ElMessage.error('上传失败');
insertFn(url);
fullscreenLoading.value = false;
}
}
},
placeholder: '请输入内容...'
};
// 自定义上传方法
const uploadFile = async (file, fileName) => {
fullscreenLoading.value = true;
let data = new FormData();
data.append('file', file);
try {
const res = await uploadFileAndImage(data);
return res;
} catch (e) {
ElMessage.error('上传失败');
fullscreenLoading.value = false;
}
};
// 组件销毁时,也及时销毁编辑器
onBeforeUnmount(() => {
const editor = editorRef.value;
if (editor == null) return;
editor.destroy();
});
const handleCreated = (editor) => {
editorRef.value = editor; // 记录 editor 实例,重要!
};
const init = () => {
valueHtml.value = props.content;
};
init();
</script>
<style lang="less" scope>
.editor {
border: 1px solid #ccc;
width: 742px;
height: 307px;
overflow: hidden;
}
.editor .w-e-modal {
height: 207px !important;
overflow: auto;
}
.editor .w-e-scroll {
height: 225px !important;
}
.editor .w-e-text-container img {
max-width: 100%;
max-height: 300px !important;
}
.w-e-text-container video {
max-height: 300px !important;
}
</style>
wangEditor5+vue3+ts
最新推荐文章于 2025-03-18 17:27:24 发布