<template>
|
<div style="width: 100%; border: 1px solid #ccc; padding-bottom: 2px">
|
<Toolbar :editor="editorRef" :defaultConfig="toolbarConfig" :mode="mode" />
|
<Editor
|
style="min-height: 380px; overflow-y: scroll"
|
v-model="html"
|
:defaultConfig="editorConfig"
|
:mode="mode"
|
@onCreated="handleCreated"
|
@onChange="handleChange"
|
@onDestroyed="handleDestroyed"
|
@onFocus="handleFocus"
|
@onBlur="handleBlur"
|
@customAlert="customAlert"
|
@customPaste="customPaste"
|
/>
|
</div>
|
</template>
|
<script setup lang="ts">
|
import { IDomEditor, IEditorConfig } from "@wangeditor/editor";
|
import "@wangeditor/editor/dist/css/style.css"; // 引入 css
|
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
|
import { getToken } from "@/utils/auth";
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
const baseUrl = import.meta.env.VITE_APP_BASE;
|
const uploadImgUrl = ref(import.meta.env.VITE_APP_BASE_API + "/tool/file/upload"); // 上传的图片服务器地址
|
const props = defineProps({
|
modelValue: {
|
type: String,
|
default: "",
|
},
|
});
|
|
const emits = defineEmits(["update:modelValue"]);
|
// onMounted(() => {
|
// if (props.modelValue) {
|
// editorRef.value!.setHtml(props.modelValue);
|
// }
|
// });
|
// console.log("uploadImgUrl======>", uploadImgUrl);
|
type InsertFnType = (url: string, alt: string, href: string) => void; //定义插入函数的类型
|
type InsertVidepFnType = (url: string, poster: string) => void;
|
const state = reactive({
|
html: "",
|
toolbarConfig: {},
|
mode: "default", // or 'simple'
|
});
|
|
// 初始化 MENU_CONF 属性
|
const editorConfig: Partial<IEditorConfig> = {
|
// TS 语法
|
placeholder: "请输入内容...", //占位内容
|
MENU_CONF: {
|
uploadImage: {
|
//自定义上传图片
|
server: uploadImgUrl.value,
|
maxFileSize: 100 * 1024 * 1024, // 100M
|
fieldName: "file",
|
// 自定义增加 http header
|
headers: {
|
Authorization: "Bearer " + getToken(),
|
ContentType: "application/json;charset=utf-8",
|
},
|
// 自定义插入图片
|
customInsert(res: any, insertFn: InsertFnType) {
|
// TS 语法
|
// customInsert(res, insertFn) { // JS 语法
|
// res 即服务端的返回结果
|
// console.log("res=============>", res);
|
// 从 res 中找到 url alt href ,然后插入图片
|
insertFn(baseUrl + res.fileName, res.name, baseUrl + res.fileName);
|
},
|
},
|
uploadVideo: {
|
server: uploadImgUrl.value,
|
fieldName: "file",
|
allowedFileTypes: ["video/*"],
|
// 单个文件的最大体积限制,默认为 10M
|
maxFileSize: 500 * 1024 * 1024, // 500M
|
// 最多可上传几个文件,默认为 5
|
maxNumberOfFiles: 1,
|
headers: {
|
Authorization: "Bearer " + getToken(),
|
ContentType: "application/json;charset=utf-8",
|
},
|
customInsert(res: any, insertFn: InsertVidepFnType) {
|
insertFn(baseUrl + res.fileName, "");
|
},
|
// 单个文件上传成功之后
|
onSuccess(file: File, res: any) {
|
// TS 语法
|
// onSuccess(file, res) { // JS 语法
|
console.log(`${file.name} 上传成功`, res);
|
proxy.$modal.msgSuccess(`${file.name} 上传成功`);
|
},
|
|
// 上传错误,或者触发 timeout 超时
|
onError(file: File, err: any, res: any) {
|
// TS 语法
|
// onError(file, err, res) { // JS 语法
|
proxy.$modal.msgError(`${file.name} 上传出错`, err, res.msg);
|
},
|
},
|
},
|
// 其他属性...
|
};
|
const editorRef = shallowRef();
|
|
const { html, toolbarConfig, mode } = toRefs(state);
|
|
// 组件销毁时,也及时销毁编辑器
|
onBeforeUnmount(() => {
|
const editor = editorRef.value;
|
if (editor == null) return;
|
editor.destroy();
|
});
|
|
const handleCreated = (editor: IDomEditor) => {
|
editorRef.value = editor;
|
if (props.modelValue) {
|
editorRef.value!.setHtml(props.modelValue);
|
}
|
// editorRef.value.txt.html(props.modelValue);
|
console.log("created", editor);
|
};
|
|
watch(
|
() => props.modelValue,
|
(newval, oldval) => {
|
editorRef.value.setHtml(newval);
|
}
|
);
|
|
const handleChange = (editor: { children: IDomEditor }) => {
|
// console.log("change:", editor.children);
|
emits("update:modelValue", state.html);
|
// console.log("-------->", state.html);
|
};
|
const handleDestroyed = (editor: IDomEditor) => {
|
console.log("destroyed", editor);
|
};
|
const handleFocus = (editor: IDomEditor) => {
|
console.log("focus", editor);
|
};
|
const handleBlur = (editor: IDomEditor) => {
|
console.log("blur", editor);
|
};
|
const customAlert = (info: IDomEditor, type: IDomEditor) => {
|
alert(`【自定义提示】${type} - ${info}`);
|
};
|
const customPaste = (editor: { insertText: (arg0: string) => void }, event: { preventDefault: () => void }, callback: (arg0: boolean) => void) => {
|
console.log("ClipboardEvent 粘贴事件对象", event);
|
// const html = event.clipboardData.getData('text/html') // 获取粘贴的 html
|
// const text = event.clipboardData.getData('text/plain') // 获取粘贴的纯文本
|
// const rtf = event.clipboardData.getData('text/rtf') // 获取 rtf 数据(如从 word wsp 复制粘贴)
|
|
// 自定义插入内容
|
// editor.insertText("xxx");
|
|
// 返回 false ,阻止默认粘贴行为
|
// event.preventDefault();
|
// callback(false); // 返回值(注意,vue 事件的返回值,不能用 return)
|
|
// 返回 true ,继续默认的粘贴行为
|
callback(true);
|
};
|
</script>
|
|
<style></style>
|