Vue使用wangEditor實(shí)現(xiàn)自定義粘貼功能
背景
收起來(lái)這個(gè)事情,那還是源于年前需求,由于急需打造公司自己的文檔中心且不啟用新的項(xiàng)目的前提下,在選取富文本編輯器這一步,果斷選擇了wangeditor這個(gè)插件,沒(méi)有考慮粘貼這種問(wèn)題,在使用的過(guò)程中,不舒適度極高,無(wú)奈之下接到了優(yōu)化需求,進(jìn)行自定義粘貼改造。
技術(shù)棧
vue2.x
@wangeditor/editor@5.1.x
自定義粘貼
官網(wǎng),已經(jīng)給出了自定義粘貼的入口,點(diǎn)擊這里
我們需要處理的,就是針對(duì)復(fù)制媒體文件和帶有格式的文本進(jìn)行特殊處理
帶有格式的文本,不保留原有格式,純粘貼文本;
圖片等媒體資源,可支持粘貼
可能出現(xiàn)的問(wèn)題及解決方案
編輯器中通過(guò)insertNode插入媒體文件之后,執(zhí)行insertText失效
- 插入一個(gè)空段落即可(下面代碼中有示例)
如何讀取剪切板中,含有的本地原生文件,(復(fù)制圖片怎么讀?。?/p>
- clipboardData.items 中,獲取每一項(xiàng)的item.getAsFile()
富文本編輯器中,怎么初始化修改插入視頻的大小 ?
- insertNode(video), 核心是使用該api去插入一個(gè)視頻節(jié)點(diǎn),它的數(shù)據(jù)結(jié)構(gòu)中加入width和height的值即可,(下面代碼中有示例)
請(qǐng)使用 ‘@customPaste’,不要放在 props 中。。。
- 出現(xiàn)類(lèi)似的報(bào)錯(cuò),請(qǐng)不要在config中使用customPaste而是用組件上的方法,改文章后續(xù)有使用示例代碼
代碼
大家期待的代碼環(huán)節(jié),
/** 異步等待 */
function sleep(delay) {
return new Promise((resolve) => {
setTimeout(() => {
resolve();
}, delay);
});
}
/**
* 插入一個(gè)空段落
* @description 為了插入圖片/視頻后,光標(biāo)不被圖片覆蓋
* @param {*} editor
*/
function insertPragraph(editor) {
const p = { type: "paragraph", children: [{ text: "" }] };
editor.insertNode(p);
}
/**
* 自定義粘貼
* @description 富文本自定義粘貼
*/
export async function customPasteItemFunc(editor, event) {
try {
/** 粘貼事件 */
const clipboardData = event.clipboardData;
if (clipboardData && clipboardData.items) {
for (let i = 0; i < clipboardData.items.length; i++) {
const item = clipboardData.items[i];
if (item.type.indexOf("image") !== -1) {
/** 粘貼圖片 */
const file = item.getAsFile();
if (file) {
const notify = this.$notify({
title: '提示',
message: '當(dāng)前有正在上傳的媒體文件',
duration: 0,
showClose: false,
type: 'warning'
});
const { code, data } = await uploadFile(file);
notify.close();
if (code !== 0) {
throw new Error("圖片上傳失敗");
}
const elem = {
type: "image",
src: data.url,
alt: "bvox",
href: "",
children: [{ text: "" }], // void node 必須包含一個(gè)空 text
};
editor.insertNode(elem); // 插入圖片
insertPragraph(editor); // 插入一個(gè)空段落
}
}
// 如果是由視頻文件
else if (item.type.indexOf("video") !== -1) {
const file = item.getAsFile();
if (file) {
const notify = this.$notify({
title: '提示',
message: '當(dāng)前有正在上傳的媒體文件',
duration: 0,
showClose: false,
type: 'warning'
});
const { code, data } = await uploadFile(file);
notify.close();
if (code !== 0) {
throw new Error("視頻上傳失敗");
}
const elem = {
type: "video",
src: data.url,
poster,
width: 530,
height: 220,
children: [{ text: "" }],
};
editor.insertNode(elem); // 插入視頻
insertPragraph(editor); // 插入一個(gè)空段落
}
} else if (item.type.indexOf("text/html") !== -1) {
// 自定義復(fù)制
const html = clipboardData.getData("text/html");
const text = clipboardData.getData("text/plain");
const resultImgs = html.match(/<img[^>]+>/g);
const imgNodes = [];
// 將匹配到的所有圖片插入到編輯器中
if (resultImgs) {
resultImgs.forEach((img) => {
const imgUrl = img.match(/src="([^"]+)"/)[1];
const elem = {
type: "image",
src: imgUrl,
alt: "bvox",
href: "",
children: [{ text: "" }], // void node 必須包含一個(gè)空 text
};
imgNodes.push(elem);
});
}
// 多圖插入
const positions = text.split("\n");
if (positions.length > 1) {
for (let i = 0; i < positions.length; i++) {
if (positions[i] === "[圖片]") {
editor.insertNode(imgNodes.shift());
insertPragraph(editor); // 插入一個(gè)空段落
await sleep(1000);
} else {
editor.insertText(positions[i]);
await sleep(300);
}
}
}
}
}
}
} catch (e) {
this.$Message.error(e.message);
}
}
大家疑惑的地方
為什么代碼中直接出現(xiàn)this.$Message.error()?
答: customPasteItemFunc.call(this, editor, event);
怎么使用這個(gè)方法呢?
答:只說(shuō)在vue中的使用,react自行去看官網(wǎng)使用即可,
<Editor
....
@customPaste="handleCustomPaste"
/>
method: {
handleCustomPaste(editor, event) {
customPasteItemFunc.call(this, editor, event);
// 阻止默認(rèn)的粘貼行為
event.preventDefault()
return false;
}
}
到此這篇關(guān)于Vue使用wangEditor實(shí)現(xiàn)自定義粘貼功能的文章就介紹到這了,更多相關(guān)Vue wangEditor自定義粘貼內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue-Router路由守衛(wèi)詳?shù)募?xì)用法教程
在Vue.js應(yīng)用中,Vue-Router是一個(gè)非常重要的插件,它允許我們實(shí)現(xiàn)頁(yè)面間的導(dǎo)航,然而,僅僅實(shí)現(xiàn)導(dǎo)航是不夠的,我們還需要在導(dǎo)航的不同階段進(jìn)行各種操作,本文將結(jié)合實(shí)際案例,詳細(xì)介紹Vue-Router路由守衛(wèi)的用法,需要的朋友可以參考下2024-12-12
Vue實(shí)現(xiàn)調(diào)用PC端攝像頭實(shí)時(shí)拍照
這篇文章主要為大家詳細(xì)介紹了Vue實(shí)現(xiàn)調(diào)用PC端攝像頭實(shí)時(shí)拍照,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09
vue如何統(tǒng)一樣式(reset.css與border.css)
這篇文章主要介紹了vue如何統(tǒng)一樣式(reset.css與border.css),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05
vue3前端axios請(qǐng)求報(bào)錯(cuò)network錯(cuò)誤的解決辦法
在使用Axios進(jìn)行網(wǎng)絡(luò)請(qǐng)求時(shí),遇到“Network?Error”報(bào)錯(cuò)可能是由多種原因?qū)е碌?這篇文章主要介紹了vue3前端axios請(qǐng)求報(bào)錯(cuò)network錯(cuò)誤的解決辦法,需要的朋友可以參考下2025-08-08
基于Vue.js實(shí)現(xiàn)簡(jiǎn)單搜索框
這篇文章主要為大家詳細(xì)介紹了基于Vue.js實(shí)現(xiàn)簡(jiǎn)單搜索框,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11
Vue3中虛擬dom轉(zhuǎn)成真實(shí)dom的過(guò)程詳解
Vue.js?在其運(yùn)行過(guò)程中會(huì)將模板編譯成虛擬?DOM?(VNode),然后再將?VNode?渲染成實(shí)際的?DOM?節(jié)點(diǎn),這個(gè)過(guò)程是由?Vue?內(nèi)部的編譯器和渲染系統(tǒng)完成的,本文給大家介紹了Vue3中虛擬dom轉(zhuǎn)成真實(shí)dom的過(guò)程,需要的朋友可以參考下2024-09-09
vuex中store存儲(chǔ)store.commit和store.dispatch的區(qū)別及說(shuō)明
這篇文章主要介紹了vuex中store存儲(chǔ)store.commit和store.dispatch的區(qū)別及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09
vue parseHTML函數(shù)源碼解析 AST預(yù)備知識(shí)
這篇文章主要為大家介紹了vue parseHTML函數(shù)源碼解析 AST預(yù)備知識(shí)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07

