React中使用Vditor自定义图片详解


Posted in Javascript onDecember 25, 2020

安装

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>
 }
}

示例:

React中使用Vditor自定义图片详解

功能使用

新建对象

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",
        ],
      }]

对应工具栏展示:

React中使用Vditor自定义图片详解

自定义按钮

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 点击事件

示例:

React中使用Vditor自定义图片详解

获取值

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 配置此方法时可实现图片粘贴并上传

React中使用Vditor自定义图片详解

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

React中使用Vditor自定义图片详解

上传完成后处理

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);
}

React中使用Vditor自定义图片详解

总结

以上是本人在接入vditor编辑器是的一些使用总结,更多相关React Vditor内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
IE中直接运行显示当前网页中的图片 推荐
Aug 31 Javascript
Js获取事件对象代码
Aug 05 Javascript
基于jQuery实现下拉框
Nov 24 Javascript
asp知识整理笔记3(问答模式)
Sep 27 Javascript
jQuery随手笔记之常用的jQuery操作DOM事件
Nov 29 Javascript
Vue.js实现模拟微信朋友圈开发demo
Apr 20 Javascript
Vue入门之数据绑定(小结)
Jan 08 Javascript
vue slot 在子组件中显示父组件传递的模板
Mar 02 Javascript
在vue中实现点击选择框阻止弹出层消失的方法
Sep 15 Javascript
jQuery实现网页拼图游戏
Apr 22 jQuery
vue遍历生成的输入框 绑定及修改值示例
Oct 30 Javascript
Vue实现导航栏的显示开关控制
Nov 01 Javascript
基于vue+echarts数据可视化大屏展示的实现
Dec 25 #Vue.js
vue3使用vue-count-to组件的实现
Dec 25 #Vue.js
js+for循环实现字符串自动转义的代码(把后面的字符替换前面的字符)
Dec 24 #Javascript
Javascript 模拟mvc实现点餐程序案例详解
Dec 24 #Javascript
vant时间控件使用方法详解
Dec 24 #Javascript
基于Vant UI框架实现时间段选择器
Dec 24 #Javascript
原生jQuery实现只显示年份下拉框
Dec 24 #jQuery
You might like
关于PHP结束标签的使用细节探讨及联想
2013/03/04 PHP
php中jpgraph类库的使用介绍
2013/08/08 PHP
php文件读取方法实例分析
2015/06/20 PHP
腾讯CMEM的PHP扩展编译安装方法
2015/09/25 PHP
javascript下function声明一些小结
2007/12/28 Javascript
Jquery中获取iframe的代码
2011/01/11 Javascript
提取字符串中年月日的函数代码
2013/11/05 Javascript
Mac地址验证的javascript代码
2013/11/09 Javascript
Javascript基础教程之数组 array
2015/01/18 Javascript
JavaScript中函数声明与函数表达式的区别详解
2016/08/18 Javascript
jQuery操作dom实现弹出页面遮罩层(web端和移动端阻止遮罩层的滑动)
2016/08/25 Javascript
利用yarn代替npm管理前端项目模块依赖的方法详解
2017/09/04 Javascript
Node.JS循环删除非空文件夹及子目录下的所有文件
2018/03/12 Javascript
JavaScript 反射和属性赋值实例解析
2019/10/28 Javascript
vue中解决拖拽改变存在iframe的div大小时卡顿问题
2020/07/22 Javascript
[02:00]最后,我终于出了辉耀
2018/03/27 DOTA
Python中的字典与成员运算符初步探究
2015/10/13 Python
Python聚类算法之基本K均值实例详解
2015/11/20 Python
判断python字典中key是否存在的两种方法
2018/08/10 Python
Python+selenium 获取浏览器窗口坐标、句柄的方法
2018/10/14 Python
python中的tcp示例详解
2018/12/09 Python
Python列表常见操作详解(获取,增加,删除,修改,排序等)
2019/02/18 Python
Python实现12306火车票抢票系统
2019/07/04 Python
python多继承(钻石继承)问题和解决方法简单示例
2019/10/21 Python
使用Rasterio读取栅格数据的实例讲解
2019/11/26 Python
Django实现后台上传并显示图片功能
2020/05/29 Python
工程师必须了解的LRU缓存淘汰算法以及python实现过程
2020/10/15 Python
英国香水店:The Perfume Shop
2017/03/27 全球购物
微软日本官方网站:Microsoft日本
2017/11/26 全球购物
日本快乐生活方式购物网站:Shop Japan
2018/07/17 全球购物
集团公司党的群众路线教育实践活动工作总结
2014/03/03 职场文书
初三新学期计划书
2014/05/03 职场文书
正科级干部考察材料
2014/05/29 职场文书
幼儿园教师节活动总结
2015/03/23 职场文书
2015年幼师个人工作总结
2015/10/15 职场文书
最新的离婚协议书范本!
2019/07/02 职场文书