又是一個風格和日立的上午,某只菜鳥高高興興的騎著小電驢去上班,本著上班只要不遲到的理念飛速前行(遲到扣錢啊~),高高興興的行走在路上。來到工位剛拴上我的繩子組長就開始滴滴俺,頓時我心中大感不妙,此時組長笑臉盈盈的走了過來說“今天有個任務交給你,至于是啥,你隨我上電腦瞅瞅”。定睛一看,原來是富文本出了問題。廢話不多說直接開始這個美麗的故事.......
????????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>