安装
npm install vditor -s
引用
导入依赖包
import Vditor from "vditor";
导入样式
import "vditor/src/assets/scss/index.scss";
使用示例
export default class Vditor extends Component {
constructor(props) {
super(props);
this.state = {
editValue: ""
};
}
componentDidMount = () => {
//组件挂载完成之后调用 注意一定要在组件挂载完成之后调用 否则会找不到注入的DOM
this.createVidtor({ value: this.state.editValue });
}
//创建编辑器 下面会详解
createVidtor = params => {
let { value } = params;
value = value ? value : " ";
let that = this;
const vditor = new Vditor("vditor", {
height: 800,
mode: "ir", //及时渲染模式
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: "发布文章",
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![${name}](${path})`;
}
document.execCommand("insertHTML", false, succFileText);
}
that.handleImageUpload(files, callback);
},
url(files) {
that.handleImageUpload(files);
}
}
});
this.vditor = vditor;
return vditor;
};
//首先需要在render里面注入DOM,可自定义注入DOM的ID,初始化编辑器的时候使用自定义的ID即可
render() {
<div className="editorWrap">
<div id="vditor" />
</div>
}
}
示例:
功能使用
新建对象
const vditor = new Vditor("vditor", ...option);
新建对象时第一个参数ID,要对应上再render里面注入的ID
option参数
tip:只列举一下常用参数,其他的参数请参照官方API
参数 | 说明 |
---|---|
height | 配置编辑器高度 |
mode | 编辑器模式 wysiwyg:所见即所得2 ir:及时渲染 sv:分屏模式 |
placeholder | 占位符 |
toolbar | 工具栏 |
Tip:如果要自定义工具栏的话,一定要加上默认的工具栏,不然只展示自定义的了
默认工具栏
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",
],
}]
对应工具栏展示:
自定义按钮
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: "发布文章",
className: "right",
icon: `<img style="height: 16px" src='https://img.58cdn.com.cn/escstatic/docs/imgUpload/idocs/publish.svg'/>`,
click() {
that.publishDoc();
}
}
]
});
//tip:在调用本类封装的方法时提前把this赋值给其他方法内的变量,在Vditor内部改变了this指向
参数 | 说明 |
---|---|
hotkey | 热键配置 |
name | 功能区分(唯一性) |
tip | 悬浮提示 |
className | UI展示 right靠右 |
icon | 按钮图标 |
click | 点击事件 |
示例:
获取值
saveDoc = () => {
//在初始化时已经把vditor赋值到this对象上 可直接通过getValue方法获取当前编辑器的值
let mdValue = this.vditor && this.vditor.getValue();
//获取完值业务保存就行 这里不再详细写本人的保存方法了
...
}
赋值
let { value } = params;
value = value ? value : " ";
//如果是空值的话 最好给一个空格 以免编辑器初始化时报错
const vditor = new Vditor("vditor", {
// value: value,
after() {
vditor.setValue(value);
}
});
//tip:虽说官方也提供value直接赋值 但是在React里面不生效,就需要在after里面去调用setValue来完成赋值
自定义图片上传
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![${name}](${path})`;
}
document.execCommand("insertHTML", false, succFileText);
}
that.handleImageUpload(files, callback);
},
url(files, callback) {
that.handleImageUpload(files, callback);
}
}
});
//此接口里面调用的是自己的图片上传 业务方自行实现
handleImageUpload = (file, callback) => {
const reader = new FileReader();
let formdata = new FormData();
formdata.append("files", file[0]);
reader.onload = () => {
// setTimeout 模拟异步上传图片
// 当异步上传获取图片地址后,执行callback回调(参数为imageUrl字符串),即可将图片地址写入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]);
};
参数 | 说明 |
---|---|
accept | 接收文件类型(我这边只做了图片上传) |
multiple | 是否多选 |
filename | 格式化文件名 |
handler | 点击数触发方法 |
url | 配置此方法时可实现图片粘贴并上传 |
图片粘贴时读取的文件
上传完成后接口返回的CDN地址
上传完成后处理
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![${name}](${path})`;
}
//拼接完直接插入到鼠标选中位置
document.execCommand("insertHTML", false, succFileText);
}
that.handleImageUpload(files, callback);
}
总结
以上是本人在接入vditor编辑器是的一些使用总结,如果您还有什么更高级的定制玩法,可留言。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。