Toast-UI/Editor工具实现图片自定义上传到服务器

author: jwensh
date: 2021.06.17

文章目录

  • Toast-UI/Editor工具实现图片自定义上传到服务器
  • 所遇问题
  • 需要解决问题
    • 1. 原 `toast-ui` 怎么处理上面三个操作的?
    • 2. 重写其中监听事件
    • 3. 服务端实现上传逻辑
    • 4. 前端具体的实现
  • 参考

所遇问题

在项目开发用到富文本框,期间使用过 Tinymcetoast-ui/editor(一款支持Markdown、WYSIWYG模式的编辑器),最后选择了 toast-ui,这里不介绍两者的区别,主要感觉它好用。遇到的问题是:富文本编辑内容时,相关资源(img、video等)如何上传到指定服务器上?

  • Toast UI Editor 版本 "@toast-ui/editor": "2.5.2"

  • VUE2 工程里使用组件和插件

    npm install @toast-ui/editor
    

需要解决问题

  1. 找到编辑器中所有涉及到资源文件的操作:图片上传截图粘贴图片拖入
  2. 将上诉操作都使用自定义操作

1. 原 toast-ui 怎么处理上面三个操作的?

默认使用 addImageBlobHook 监听事件将图片转换成 Base64 追加到文本中

Toast UI Editor 支持三种图片上传方式:弹窗选择拖拽截屏粘贴;三种上传方式最终都会被 addImageBlobHook 监听,并处理为 Base64 格式的图片;

  • 此处为默认的 addImageBlobHook 监听事件,位于 src/js/importManager.js 中 第:124 行
  /*** Initialize default image importer* @private*/_initDefaultImageImporter() {this.eventManager.listen('addImageBlobHook', (blob, callback) => {const reader = new FileReader();reader.onload = event => {callback(event.target.result);};reader.readAsDataURL(blob);});}

2. 重写其中监听事件

  • 先看下是否有事件相关的设置方法
  • eventManager.js 中提供了删除监听事件的函数 removeEventHandler(typeStr, handler) 第 210行
/*** Remove event handler from given event type* @param {string} typeStr Event type name* @param {function} [handler] - registered event handler*/removeEventHandler(typeStr, handler) {const { type, namespace } = this._getTypeInfo(typeStr);if (type && handler) {this._removeEventHandlerWithHandler(type, handler);} else if (type && !namespace) {// dont use dot notation cuz eslintthis.events.delete(type);} else if (!type && namespace) {this.events.forEach((eventHandlers, eventType) => {this._removeEventHandlerWithTypeInfo(eventType, namespace);});} else if (type && namespace) {this._removeEventHandlerWithTypeInfo(type, namespace);}}
  • 所以,第一步:去掉默认的 addImageBlobHook 监听事件
// 删除默认监听事件
this.editor.eventManager.removeEventHandler('addImageBlobHook')
  • 第二步:添加自定义的 addImageBlobHook 监听事件
// 添加自定义监听事件
this.editor.eventManager.listen('addImageBlobHook', (blob, callback) => {// 此处填写自己的上传逻辑,url为上传后的图片地址this.uploadFile(blob, url => {callback(url)})
})

3. 服务端实现上传逻辑

后端服务实现一个可以上传文件的接口,单文件上传即可;语言自行选择,静态文件可以使用 nginx 挂载

4. 前端具体的实现

  • vue的源码
<template><div :id="id" />
</template><script>
/*** @author jwensh* 这里使用 @toast-ui/editor@v2.5.2 版本的markdown编辑器
*/
import 'codemirror/lib/codemirror.css' // Editor's Dependency Style
import '@toast-ui/editor/dist/toastui-editor.css' // Editor's Styleimport Editor from '@toast-ui/editor'
import defaultOptions from './default-options'export default {name: 'MarddownEditor',props: {value: {type: String,default: ''},id: {type: String,required: false,default() {return 'markdown-editor-' + +new Date() + ((Math.random() * 1000).toFixed(0) + '')}},options: {type: Object,default() {return defaultOptions}},mode: {type: String,default: 'wysiwyg'},height: {type: String,required: false,default: '300px'},language: {type: String,required: false,default: 'en_US'}},data() {return {editor: null}},computed: {editorOptions() {const options = Object.assign({}, defaultOptions, this.options)options.initialEditType = this.modeoptions.height = this.heightoptions.language = this.languagereturn options}},watch: {value(newValue, preValue) {if (newValue !== preValue && newValue !== this.editor.getHtml()) {this.editor.setHtml(newValue)}},language(val) {this.destroyEditor()this.initEditor()},height(newValue) {this.editor.height(newValue)},mode(newValue) {this.editor.changeMode(newValue)}},mounted() {this.initEditor()},methods: {initEditor() {this.editor = new Editor({el: document.getElementById(this.id),...this.editorOptions})if (this.value) {this.editor.setHtml(this.value)}this.editor.on('blur', () => {this.$emit('updateContent', this.editor.getHtml())})// 删除默认监听事件后,添加自定义监听事件this.editor.eventManager.removeEventHandler('addImageBlobHook')this.editor.eventManager.listen('addImageBlobHook', (blob, callback) => {// 此处填写自己的上传逻辑,url为上传后的图片地址const formData = new FormData()formData.append('files', blob)const ajax = new XMLHttpRequest()ajax.open('POST', 'http://***/v1/uploadfiles?user_id=jwensh', true)ajax.send(formData)ajax.onreadystatechange = function() {if (ajax.readyState === 4) {if ((ajax.status >= 200 && ajax.status < 300) || ajax.status === 304) {const obj = JSON.parse(ajax.responseText)if (obj.code && obj.code === 'true') {callback(obj.result.root_path + obj.result.url)}}}}})}}
}
</script>

到此算是解决三种方式(Popup、Drag、Screenshot)按照自己的上传逻辑进行图片上传

参考

  1. https://github.com/nhn/tui.editor
  2. https://nhn.github.io/tui.editor/latest/tutorial-example01-editor-basic

【VUE】Toast-UI/Editor工具实现图片自定义上传到服务器相关推荐

  1. 富文本wangeditor图片自定义上传及图片删除

    富文本编辑器的组件有很多像:百度的UEditor ,Vue-Quill-Editor,以及wangeditor. 组件的选择根据自己业务需求选择,本文选用的是wangeditor. 首先说一下业务需求 ...

  2. 基于vue + axios + lrz.js 微信端图片压缩上传

    业务场景 微信端项目是基于Vux + Axios构建的,关于图片上传的业务场景有以下几点需求: 1.单张图片上传(如个人头像,实名认证等业务) 2.多张图片上传(如某类工单记录) 3.上传图片时期望能 ...

  3. 画世界上传图片提交到服务器_【MUI】选择图片并上传至服务器

    最后更新17.01.20 一.首先这是HTML的代码 将要显示一张图片 二.然后这是JavaScript代码 var img_my = document.getElementById('my_img_ ...

  4. html5在线裁剪,HTML5 本地裁剪图片并上传至服务器(老梗)

    很多情况下用户上传的图片都需要经过裁剪,比如头像啊什么的.但以前实现这类需求都很复杂,往往需要先把图片上传到服务器,然后返回给用户,让用户确定裁剪坐标,发送给服务器,服务器裁剪完再返回给用户,来回需要 ...

  5. cocos creator 调用相机相册裁剪图片并上传到服务器

    大致思路就是creator里面js调用Java和object-c代码,调起系统相机相册,选取图库图片/拍照图片进行裁剪,然后转化为base64字符串,最后通过http post请求上传到服务器. Ja ...

  6. html5图片区域剪切,HTML5 本地裁剪图片并上传至服务器(老梗)

    很多情况下用户上传的图片都需要经过裁剪,比如头像啊什么的.但以前实现这类需求都很复杂,往往需要先把图片上传到服务器,然后返回给用户,让用户确定裁剪坐标,发送给服务器,服务器裁剪完再返回给用户,来回需要 ...

  7. ueditor 图片上传 java_Spring+Vue整合UEditor富文本实现图片附件上传的方法

    下载UEditor 下载完整源码和JSP版本 Spring后端集成 1. 解压完整源码,拷贝jsp目录下的java源码,到spring mvc后端 jsp目录下java源码 集成spring mvc后 ...

  8. vue使用cropperjs实现移动端图片裁剪上传组件

    本组件基于vuejs框架, 使用ES6基本语法, css预编译采用的scss, 图片裁剪模块基于cropperjs,拍照时的图片信息获取使用exif, 图片上传使用XMLHttpRequest 该组件 ...

  9. Element UI结合vue-cropper打造图片裁剪上传组件

    效果显示 引用vue-cropper npm install vue-cropperyarn add vue-cropper 创建组件文件夹 上传按钮组件 index.vue <template ...

最新文章

  1. pcl需要注意的编译问题
  2. C++中对多态的理解
  3. 强大实用的DISM命令
  4. Sharepoint 弹出消息提示框
  5. mysql libc.so.6_解决安装mysql动态库libstdc++.so.6、libc.so.6版本过低问题
  6. Linux 基本命令(三)--histroy 常用命令详解
  7. main:处理命令行选项
  8. mac迅雷精简版(迅雷Mac)简约瘦身版
  9. win10系统禁用音频服务器,Win10下怎样设置禁用扬声器、插入耳机有声音【图文教程】...
  10. java、web前端开发日常记录
  11. 我的理想计算机系100字,我的理想作文100字(通用12篇)
  12. 治愈系英语笔记-2-一般、否定疑问句,现表将来
  13. 怎么看cf的服务器在哪个文件夹,cf录像在哪个文件夹
  14. 解决dell 15R 双显卡笔记本桌面右键点击反应慢的问题
  15. 【在线翻译英文】的网站
  16. C++多项式除法的探讨
  17. 周末和新润视频聊天了
  18. map与sync.Map
  19. 为大家介绍一下自制DIY面膜的好地方
  20. Python 二维离散傅里叶变换

热门文章

  1. 荣誉 | 旷视再次入选《麻省理工科技评论》50家聪明公司​
  2. 【银行架构day1】一个银行的信息系统架构是什么样子
  3. Python 字符串基本操作
  4. tg170板材_TG板材的特点优势,TG150、TG170板材有何差异
  5. 音效素材网站分享,各种音效配乐应有尽有,做自媒体必备
  6. 学HTML就看这篇呀(HTML详解)
  7. 当PBlaze6 6920 Raid阵列遇到FC SAN
  8. matlab中短时傅里叶变换tfrstft函数用法
  9. thinkphp 5.0下载网络图片
  10. JS中栈和堆的区别?