又是一个风格和日立的上午,某只菜鸟高高兴兴的骑着小电驴去上班,本着上班只要不迟到的理念飞速前行(迟到扣钱啊~),高高兴兴的行走在路上。来到工位刚拴上我的绳子组长就开始滴滴俺,顿时我心中大感不妙,此时组长笑脸盈盈的走了过来说“今天有个任务交给你,至于是啥,你随我上电脑瞅瞅”。定睛一看,原来是富文本出了问题。废话不多说直接开始这个美丽的故事.......
wangeditor富文本功能挺强大的。官网链接:优势 | wangEditor
本文主要讲到粘贴文字这一块的处理,从浏览器上粘过来的文字一般都带有一些自己的样式,可能肉眼看到是黑色,其实是个灰色,主要修改粘贴后文字默认展示黑色。
一、粘贴函数介绍
customPaste用于处理粘贴的函数,官网有介绍。
<Editorv-model="valueHtml":defaultConfig="editorConfig":mode="mode":style="{'height': props.height,'overflow-y': 'hidden','width': `${100}%`}"@on-created="handleCreated"@on-change="onChange"@custom-paste="customPaste"
二、customPaste函数逻辑
// 自定义粘贴处理器
const customPaste = (editor: any, event: any) => {// 在preventDefault之前先获取内容const clipboardData = event.clipboardData;const html = clipboardData.getData('text/html');const text = clipboardData.getData('text/plain');event.preventDefault(); // 阻止默认粘贴行为// 如果有HTML内容,进行处理if (html) {console.log("开始处理HTML内容");// 创建临时DOM元素const tempDiv = document.createElement('div');tempDiv.innerHTML = html;// 遍历所有元素,移除 style.color 属性const elements = tempDiv.querySelectorAll('*');elements.forEach(el => {const element = el as HTMLElement;if (element.style.color) {element.style.removeProperty('color');}// 也可以考虑移除 background-color 如果需要// if (element.style.backgroundColor) {// element.style.removeProperty('background-color');// }});// 获取清理后的 HTML 字符串const cleanHtml = tempDiv.innerHTML;// 将处理后的HTML插入编辑器editor.dangerouslyInsertHtml(cleanHtml);} else if (text) {// 处理纯文本内容// 插入纯文本,并可以设置默认样式editor.insertText(text);}
}
三、如果想加强一下效果
设置默认值,加强魔法
const editorConfig = {placeholder: "请输入内容...",MENU_CONF: {},readOnly: props.readOnly,// 设置默认文本颜色为黑色defaultStyle: {color: '#000000'}
};
四、完整代码
<script setup lang="ts">
import { uploadFile } from "@/utils/upload/upload.js";
import { onBeforeUnmount, ref, shallowRef, defineProps } from "vue";
import "@wangeditor/editor/dist/css/style.css";
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import { getObjVal, to } from "@iceywu/utils";
import { ElLoading } from "element-plus";defineOptions({name: "PicUpload"
});
const props = defineProps({isOpen: {type: Boolean,default: true},height: {type: String,default: "500px"},readOnly: {type: Boolean,default: false}
});
const emit = defineEmits(["handleChange"]);const valueHtml = defineModel<string>({default: ""
});const mode = "default";
// 编辑器实例,必须用 shallowRef
const editorRef = shallowRef();// 内容 HTML
// const valueHtml = ref(
// "<p>仅提供代码参考,暂不可上传图片,可根据实际业务改写</p>"
// );
const toolbarConfig: any = { excludeKeys: "fullScreen" };
const editorConfig = {placeholder: "请输入内容...",MENU_CONF: {},readOnly: props.readOnly,// 设置默认文本颜色为黑色defaultStyle: {color: '#000000'}
};// 更多详细配置看 https://www.wangeditor.com/v5/menu-config.html#%E4%B8%8A%E4%BC%A0%E5%9B%BE%E7%89%87
editorConfig.MENU_CONF["uploadImage"] = {// 服务端上传地址,根据实际业务改写server: "",// form-data 的 fieldName,根据实际业务改写fieldName: "file",// 选择文件时的类型限制,根据实际业务改写allowedFileTypes: ["image/png", "image/jpg", "image/jpeg"],// 自定义上传async customUpload(file: File, insertFn: any) {const loading = ElLoading.service({ text: "上传中..." }) as any;const result = (await to(uploadFile(file, res => {const { percent, stage = "upload" } = res;loading.text = `上传中...${percent}%`;})))[1] as any;console.log("🍭-----result-----", result);loading.close();// const { url, name } = result || {};const url = getObjVal(result, "data.url", "");const name = getObjVal(result, "data.fileName", "");console.log("🐬-----url, name-----", url, name);insertFn(url, name, url);}
};
editorConfig.MENU_CONF["uploadVideo"] = {// 服务端上传地址,根据实际业务改写server: "",// form-data 的 fieldName,根据实际业务改写fieldName: "file",// 选择文件时的类型限制,根据实际业务改写allowedFileTypes: ["video/*"],// 自定义上传async customUpload(file: File, insertFn: any) {const loading = ElLoading.service({ text: "上传中..." }) as any;const result = (await to(uploadFile(file, res => {const { percent, stage = "upload" } = res;loading.text = `上传中...${percent}%`;})))[1] as any;console.log("🍭-----result-----", result);loading.close();// const { url, name } = result || {};const url = getObjVal(result, "data.url", "");const name = getObjVal(result, "data.fileName", "");console.log("🐬-----url, name-----", url, name);insertFn(url, name, url);}
};const handleCreated = editor => {// 记录 editor 实例,重要!editorRef.value = editor;
};// 组件销毁时,也及时销毁编辑器
onBeforeUnmount(() => {const editor = editorRef.value;if (editor == null) return;editor.destroy();
});
const onChange = (val: any) => {const valTemp = val.getHtml();emit("handleChange", valTemp);
};// 自定义粘贴处理器
const customPaste = (editor: any, event: any) => {// 在preventDefault之前先获取内容const clipboardData = event.clipboardData;const html = clipboardData.getData('text/html');const text = clipboardData.getData('text/plain');event.preventDefault(); // 阻止默认粘贴行为// 如果有HTML内容,进行处理if (html) {console.log("开始处理HTML内容");// 创建临时DOM元素const tempDiv = document.createElement('div');tempDiv.innerHTML = html;// 遍历所有元素,移除 style.color 属性const elements = tempDiv.querySelectorAll('*');elements.forEach(el => {const element = el as HTMLElement;if (element.style.color) {element.style.removeProperty('color');}// 也可以考虑移除 background-color 如果需要// if (element.style.backgroundColor) {// element.style.removeProperty('background-color');// }});// 获取清理后的 HTML 字符串const cleanHtml = tempDiv.innerHTML;// 将处理后的HTML插入编辑器editor.dangerouslyInsertHtml(cleanHtml);} else if (text) {// 处理纯文本内容// 插入纯文本,并可以设置默认样式editor.insertText(text);}
}
</script><template><div class="wangeditor"><Toolbarv-if="props.isOpen":editor="editorRef":defaultConfig="toolbarConfig":mode="mode"style="border-bottom: 1px solid #ccc"/><Editorv-model="valueHtml":defaultConfig="editorConfig":mode="mode":style="{'height': props.height,'overflow-y': 'hidden','width': `${100}%`}"@on-created="handleCreated"@on-change="onChange"@custom-paste="customPaste"/></div>
</template><style lang="scss" scoped>
.table_top {background-color: #fff;
}:deep(.w-e-text-container) {.w-e-scroll {p {margin: 5px !important;}}
}
:deep(.w-e-text-placeholder) {left: 14px;top: 1px;
}
</style>