React中使用Vditor自定義圖片詳解
安裝
npm install vditor -s
引用
導(dǎo)入依賴(lài)包
import Vditor from "vditor";
導(dǎo)入樣式
import "vditor/src/assets/scss/index.scss";
使用示例
export default class Vditor extends Component {
constructor(props) {
super(props);
this.state = {
editValue: ""
};
}
componentDidMount = () => {
//組件掛載完成之后調(diào)用 注意一定要在組件掛載完成之后調(diào)用 否則會(huì)找不到注入的DOM
this.createVidtor({ value: this.state.editValue });
}
//創(chuàng)建編輯器 下面會(huì)詳解
createVidtor = params => {
let { value } = params;
value = value ? value : " ";
let that = this;
const vditor = new Vditor("vditor", {
height: 800,
mode: "ir", //及時(shí)渲染模式
placeholder: "React Vditor",
toolbar: [
"emoji",
"headings",
"bold",
"italic",
"strike",
"link",
"|",
"list",
"ordered-list",
"check",
"outdent",
"indent",
"|",
"quote",
"line",
"code",
"inline-code",
"insert-before",
"insert-after",
"|",
"upload",
"table",
"|",
"undo",
"redo",
"|",
"fullscreen",
"edit-mode",
{
name: "more",
toolbar: [
"both",
"code-theme",
"content-theme",
"export",
"outline",
"preview",
"devtools",
"info",
"help"
]
},
"|",
{
hotkey: "⌘-S",
name: "save",
tipPosition: "s",
tip: "保存",
className: "right",
icon: `<img style="height: 16px" src='https://img.58cdn.com.cn/escstatic/docs/imgUpload/idocs/save.svg'/>`,
click() {
that.saveDoc();
}
},
{
hotkey: "",
name: "publish",
tipPosition: "s",
tip: "發(fā)布文章",
className: "right",
icon: `<img style="height: 16px" src='https://img.58cdn.com.cn/escstatic/docs/imgUpload/idocs/publish.svg'/>`,
click() {
that.publishDoc();
}
}
],
after() {
vditor.setValue(value);
},
blur() {
that.saveDoc();
},
upload: {
accept: "image/*",
multiple: false,
filename(name) {
return name
.replace(/[^(a-zA-Z0-9\u4e00-\u9fa5\.)]/g, "")
.replace(/[\?\\/:|<>\*\[\]\(\)\$%\{\}@~]/g, "")
.replace("/\\s/g", "");
},
handler(files) {
function callback(path) {
let name = files[0] && files[0].name;
let succFileText = "";
if (vditor && vditor.vditor.currentMode === "wysiwyg") {
succFileText += `\n <img alt=${name} src="${path}">`;
} else {
succFileText += ` \n`;
}
document.execCommand("insertHTML", false, succFileText);
}
that.handleImageUpload(files, callback);
},
url(files) {
that.handleImageUpload(files);
}
}
});
this.vditor = vditor;
return vditor;
};
//首先需要在render里面注入DOM,可自定義注入DOM的ID,初始化編輯器的時(shí)候使用自定義的ID即可
render() {
<div className="editorWrap">
<div id="vditor" />
</div>
}
}
示例:

功能使用
新建對(duì)象
const vditor = new Vditor("vditor", ...option);
新建對(duì)象時(shí)第一個(gè)參數(shù)ID,要對(duì)應(yīng)上再render里面注入的ID
option參數(shù)
tip:只列舉一下常用參數(shù),其他的參數(shù)請(qǐng)參照 官方API
| 參數(shù) | 說(shuō)明 |
|---|---|
| height | 配置編輯器高度 |
| mode | 編輯器模式 wysiwyg:所見(jiàn)即所得2 ir:及時(shí)渲染 sv:分屏模式 |
| placeholder | 占位符 |
| toolbar | 工具欄 |
Tip:如果要自定義工具欄的話(huà),一定要加上默認(rèn)的工具欄,不然只展示自定義的了
默認(rèn)工具欄
tip:此為源碼里面copy 不用更改可直接使用,官方已定義好了快捷鍵和功能
toolbar: [
"emoji",
"headings",
"bold",
"italic",
"strike",
"link",
"|",
"list",
"ordered-list",
"check",
"outdent",
"indent",
"|",
"quote",
"line",
"code",
"inline-code",
"insert-before",
"insert-after",
"|",
"upload",
"record",
"table",
"|",
"undo",
"redo",
"|",
"fullscreen",
"edit-mode",
{
name: "more",
toolbar: [
"both",
"code-theme",
"content-theme",
"export",
"outline",
"preview",
"devtools",
"info",
"help",
],
}]
對(duì)應(yīng)工具欄展示:

自定義按鈕
let that = this;
const vditor = new Vditor("vditor", {
toolbar: [
{
hotkey: "⌘-S",
name: "save",
tipPosition: "s",
tip: "保存",
className: "right",
icon: `<img style="height: 16px" src='https://img.58cdn.com.cn/escstatic/docs/imgUpload/idocs/save.svg'/>`,
click() {
that.saveDoc();
}
},
{
hotkey: "",
name: "publish",
tipPosition: "s",
tip: "發(fā)布文章",
className: "right",
icon: `<img style="height: 16px" src='https://img.58cdn.com.cn/escstatic/docs/imgUpload/idocs/publish.svg'/>`,
click() {
that.publishDoc();
}
}
]
});
//tip:在調(diào)用本類(lèi)封裝的方法時(shí)提前把this賦值給其他方法內(nèi)的變量,在Vditor內(nèi)部改變了this指向
| 參數(shù) | 說(shuō)明 |
|---|---|
| hotkey | 熱鍵配置 |
| name | 功能區(qū)分(唯一性) |
| tip | 懸浮提示 |
| className | UI展示 right靠右 |
| icon | 按鈕圖標(biāo) |
| click | 點(diǎn)擊事件 |
示例:

獲取值
saveDoc = () => {
//在初始化時(shí)已經(jīng)把vditor賦值到this對(duì)象上 可直接通過(guò)getValue方法獲取當(dāng)前編輯器的值
let mdValue = this.vditor && this.vditor.getValue();
//獲取完值業(yè)務(wù)保存就行 這里不再詳細(xì)寫(xiě)本人的保存方法了
...
}
賦值
let { value } = params;
value = value ? value : " ";
//如果是空值的話(huà) 最好給一個(gè)空格 以免編輯器初始化時(shí)報(bào)錯(cuò)
const vditor = new Vditor("vditor", {
// value: value,
after() {
vditor.setValue(value);
}
});
//tip:雖說(shuō)官方也提供value直接賦值 但是在React里面不生效,就需要在after里面去調(diào)用setValue來(lái)完成賦值
自定義圖片上傳
const vditor = new Vditor("vditor", {
upload: {
accept: "image/*",
multiple: false,
filename(name) {
return name
.replace(/[^(a-zA-Z0-9\u4e00-\u9fa5\.)]/g, "")
.replace(/[\?\\/:|<>\*\[\]\(\)\$%\{\}@~]/g, "")
.replace("/\\s/g", "");
},
handler(files) {
function callback(path) {
let name = files[0] && files[0].name;
let succFileText = "";
if (vditor && vditor.vditor.currentMode === "wysiwyg") {
succFileText += `\n <img alt=${name} src="${path}">`;
} else {
succFileText += ` \n`;
}
document.execCommand("insertHTML", false, succFileText);
}
that.handleImageUpload(files, callback);
},
url(files, callback) {
that.handleImageUpload(files, callback);
}
}
});
//此接口里面調(diào)用的是自己的圖片上傳 業(yè)務(wù)方自行實(shí)現(xiàn)
handleImageUpload = (file, callback) => {
const reader = new FileReader();
let formdata = new FormData();
formdata.append("files", file[0]);
reader.onload = () => {
// setTimeout 模擬異步上傳圖片
// 當(dāng)異步上傳獲取圖片地址后,執(zhí)行callback回調(diào)(參數(shù)為imageUrl字符串),即可將圖片地址寫(xiě)入markdown
new Promise(resolve => {
this.props.dispatch({
type: "docManager/imageUpload",
payload: { resolve, username: myInfo.userId, formdata }
});
}).then(res => {
let imgurl = res.result.path;
callback(imgurl);
});
};
reader.readAsDataURL(file[0]);
};
| 參數(shù) | 說(shuō)明 |
|---|---|
| accept | 接收文件類(lèi)型(我這邊只做了圖片上傳) |
| multiple | 是否多選 |
| filename | 格式化文件名 |
| handler | 點(diǎn)擊數(shù)觸發(fā)方法 |
| url | 配置此方法時(shí)可實(shí)現(xiàn)圖片粘貼并上傳 |

上傳完成后接口返回的CDN地址

上傳完成后處理
handler(files) {
function callback(path) {
let name = files[0] && files[0].name;
let succFileText = "";
//上傳完成獲取當(dāng)前編輯器模式 根據(jù)不同模式拼接不同的展示標(biāo)簽
if (vditor && vditor.vditor.currentMode === "wysiwyg") {
succFileText += `\n <img alt=${name} src="${path}">`;
} else {
succFileText += ` \n`;
}
//拼接完直接插入到鼠標(biāo)選中位置
document.execCommand("insertHTML", false, succFileText);
}
that.handleImageUpload(files, callback);
}

總結(jié)
以上是本人在接入vditor編輯器是的一些使用總結(jié),更多相關(guān)React Vditor內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
react router4+redux實(shí)現(xiàn)路由權(quán)限控制的方法
本篇文章主要介紹了react router4+redux實(shí)現(xiàn)路由權(quán)限控制的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-05-05
React styled components樣式組件化使用流程
styled-components 是react的一個(gè)第三方庫(kù),一種css私有化的方式。用來(lái)實(shí)現(xiàn)CSS in JS 的方式之一。在多人協(xié)作中,css必定會(huì)出現(xiàn)命名沖突,與vue的scoped解決方案不同,react用styled-components的給類(lèi)名加了隨機(jī)字符的方式實(shí)現(xiàn)了css的私有化2023-02-02
React項(xiàng)目打包發(fā)布到Tomcat頁(yè)面空白問(wèn)題及解決
這篇文章主要介紹了React項(xiàng)目打包發(fā)布到Tomcat頁(yè)面空白問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06
react的ui庫(kù)antd中form表單使用SelectTree反顯問(wèn)題及解決
這篇文章主要介紹了react的ui庫(kù)antd中form表單使用SelectTree反顯問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01
React中的useState和setState的執(zhí)行機(jī)制詳解
這篇文章主要介紹了React中的useState和setState的執(zhí)行機(jī)制,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03
React中的render何時(shí)執(zhí)行過(guò)程
這篇文章主要介紹了React中的render何時(shí)執(zhí)行過(guò)程,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-04-04

