news 2026/2/8 8:03:25

TinyMCE5处理政府公文修订记录保留

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
TinyMCE5处理政府公文修订记录保留

关于Vue内使用tinymce图片上传粘贴相关问题

最近因为工作需要,用到了富文本编辑器让用户填写反馈,上传图片等功能,经过一些对比选择了tinymce,记录下图片相关问题。
完整版封装的组件代码,放到最后。

环境

vue2.x
tinymce 5.10.3
tinymce-vue 2.1.0

这里由于开发环境是vue2,所以目前这个时间点,需要选择版本的去安装,引用官方文档的一句话

Version 4 of the tinymce-vue package supports Vue.js 3.x, but does not support Vue.js 2.x. For Vue.js 2.x applications, use tinymce-vue version 3.

图片上传

这个比较简单,在init的配置中,配置images_upload_handler

...data(){init{images_upload_handler:this.handleImageUpload}},methods:{handleImageUpload(blobInfo,success,failure){// 将图片上传到服务器.let formdata=newFormData()formdata.append('file',blobInfo.blob(),blobInfo.filename())this.uploadImage(formdata).then(success).catch(failure)},uploadImage(formdata){returnnewPromise((resolve,reject)=>{Axios({url:'https://xxxx.xx.com/xxx/xxx',method:'post',data:formdata,headers:{'Content-Type':'multipart/form-data'}}).then(result=>{console.log(result)if(result.status!==200||result.data.code!=='200'){constmsg='上传失败'reject(msg)}else{resolve(result.data.data)}})})}}

图片粘贴

刚开始是想到的直接监听document的paste事件,去获取剪切板的图片,代码如下:

// 代码引用至张鑫旭的个人网站文章// https://www.zhangxinxu.com/wordpress/2018/09/ajax-upload-image-from-clipboard/document.addEventListener('paste',function(event){varitems=event.clipboardData&&event.clipboardData.items;varfile=null;if(items&&items.length){// 检索剪切板itemsfor(vari=0;i<items.length;i++){if(items[i].type.indexOf('image')!==-1){file=items[i].getAsFile();break;}}}// 此时file就是剪切板中的图片文件});

后来发现不生效,检查一下元素得知,tinymce是通过iframe使用的,
所以在tinymce输入框内,paste事件无法触发
后来找到了init_instance_callback配置项,返回的实例可以监听粘贴事件

init:{init_instance_callback:editor=>{editor.on('paste',e=>{})}}

粘贴监听算是解决了,接下来要处理的是,粘贴后如何如何替换图片。
因为默认粘贴进去的图片,是以base64存在的,这样直接存进数据库不好,所以需要将base64替换。
刚开始想到的是,将base64删除,然后替换新的img标签进去,这样存在一个问题,就是如果上传图片的网络慢,用户多次粘贴,或者输入文字,图片的位置就会错位.
最后这里选择了在用户一粘贴,拿到base64,上传成功后替换即可。代码如下

methods:{listenImgPaste(event){returnnewPromise(resolve=>{constitems=event.clipboardData&&event.clipboardData.itemsletfile=nullif(items&&items.length){for(leti=0;i<items.length;i++){if(items[i].type.indexOf('image')!==-1){file=items[i].getAsFile()break}}}if(file){setTimeout(()=>{// 获取当前图片的base64constbase64=this.myValue.match(/src="data:image.*?"/g)letformdata=newFormData()formdata.append('file',file)this.uploadImage(formdata).then(url=>{// 成功后将base64替换this.myValue=this.myValue.replace(base64,`src="${url}"`)resolve()})})}})},}

成功实现。
最后一个问题,替换修改值以后,tinymce会默认将光标定位到最前面,体验不是很好,最后的解决方法也是加配置

init:{init_instance_callback:editor=>{// 初始化后移动光标到最后this.moveCursorToLast(editor)console.log(editor)editor.on('paste',asyncevent=>{awaitthis.listenImgPaste(event)this.moveCursorToLast(editor)})}}methods:{// 移动光标到最后moveCursorToLast(editor){editor.selection.select(editor.getBody(),true)editor.selection.collapse(false)}}

最后的完整组件代码

// word导入插件(function(){'use strict';varglobal=tinymce.util.Tools.resolve('tinymce.PluginManager');functionselectLocalImages(editor){WordPaster.getInstance().SetEditor(editor).importWord()}varregister$1=function(editor){editor.ui.registry.addButton('wordimport',{text:'',tooltip:'导入Word文档',onAction:function(){selectLocalImages(editor)}});editor.ui.registry.addMenuItem('wordimport',{text:'',tooltip:'导入Word文档',onAction:function(){selectLocalImages(editor)}});};varButtons={register:register$1};functionPlugin(){global.add('wordimport',function(editor){Buttons.register(editor);});}Plugin();}());// word粘贴插件(function(){'use strict';varglobal=tinymce.util.Tools.resolve('tinymce.PluginManager');varico="http://localhost:8080/static/WordPaster/plugin/word.png"functionselectLocalImages(editor){WordPaster.getInstance().SetEditor(editor).PasteManual()}varregister$1=function(editor){editor.ui.registry.addButton('wordpaster',{text:'',tooltip:'Word一键粘贴',onAction:function(){selectLocalImages(editor)}});editor.ui.registry.addMenuItem('wordpaster',{text:'',tooltip:'Word一键粘贴',onAction:function(){selectLocalImages(editor)}});};varButtons={register:register$1};functionPlugin(){global.add('wordpaster',function(editor){Buttons.register(editor);});}Plugin();}());// ppt导入插件(function(){'use strict';varglobal=tinymce.util.Tools.resolve('tinymce.PluginManager');functionselectLocalImages(editor){WordPaster.getInstance().SetEditor(editor);WordPaster.getInstance().importPPT()}varregister$1=function(editor){editor.ui.registry.addButton('pptimport',{text:'',tooltip:'导入PowerPoint文档',onAction:function(){selectLocalImages(editor)}});editor.ui.registry.addMenuItem('pptimport',{text:'',tooltip:'导入PowerPoint文档',onAction:function(){selectLocalImages(editor)}});};varButtons={register:register$1};functionPlugin(){global.add('pptimport',function(editor){Buttons.register(editor);});}Plugin();}());// pdf导入插件(function(){'use strict';varglobal=tinymce.util.Tools.resolve('tinymce.PluginManager');functionselectLocalImages(editor){WordPaster.getInstance().SetEditor(editor);WordPaster.getInstance().ImportPDF()}varregister$1=function(editor){editor.ui.registry.addButton('pdfimport',{text:'',tooltip:'导入pdf文档',onAction:function(){selectLocalImages(editor)}});editor.ui.registry.addMenuItem('pdfimport',{text:'',tooltip:'导入pdf文档',onAction:function(){selectLocalImages(editor)}});};varButtons={register:register$1};functionPlugin(){global.add('pdfimport',function(editor){Buttons.register(editor);});}Plugin();}());// 网络图片上传插件(function(){'use strict';varglobal=tinymce.util.Tools.resolve('tinymce.PluginManager');functionselectLocalImages(editor){WordPaster.getInstance().SetEditor(editor);WordPaster.getInstance().UploadNetImg()}varregister$1=function(editor){editor.ui.registry.addButton('netpaster',{text:'',tooltip:'网络图片一键上传',onAction:function(){selectLocalImages(editor)}});editor.ui.registry.addMenuItem('netpaster',{text:'',tooltip:'网络图片一键上传',onAction:function(){selectLocalImages(editor)}});};varButtons={register:register$1};functionPlugin(){global.add('netpaster',function(editor){Buttons.register(editor);});}Plugin();}());// excel导入插件(function(){'use strict';varglobal=tinymce.util.Tools.resolve('tinymce.PluginManager');functionselectLocalImages(editor){WordPaster.getInstance().SetEditor(editor).importExcel()}varregister$1=function(editor){editor.ui.registry.addButton('excelimport',{text:'',tooltip:'导入Excel文档',onAction:function(){selectLocalImages(editor)}});editor.ui.registry.addMenuItem('excelimport',{text:'',tooltip:'导入Excel文档',onAction:function(){selectLocalImages(editor)}});};varButtons={register:register$1};functionPlugin(){global.add('excelimport',function(editor){Buttons.register(editor);});}Plugin();}());// word转图片插件(function(){'use strict';varglobal=tinymce.util.Tools.resolve('tinymce.PluginManager');functionselectLocalImages(editor){WordPaster.getInstance().SetEditor(editor);WordPaster.getInstance().importWordToImg()}varregister$1=function(editor){editor.ui.registry.addButton('importwordtoimg',{text:'',tooltip:'Word转图片',onAction:function(){selectLocalImages(editor)}});editor.ui.registry.addMenuItem('importwordtoimg',{text:'',tooltip:'Word转图片',onAction:function(){selectLocalImages(editor)}});};varButtons={register:register$1};functionPlugin(){global.add('importwordtoimg',function(editor){Buttons.register(editor);});}Plugin();}());

引用

import tinymce from '../../../common/tinymce' export default { name: 'createFeedback', components: { tinymce }, data () { return { form: { des: '' } } }

下载插件

下载插件

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/3 0:41:09

28、全面解析用户管理:从基础操作到高级安全设置

全面解析用户管理:从基础操作到高级安全设置 在系统管理的领域中,用户管理是至关重要的一环。系统管理员需要对用户和用户组进行全面的管理,包括添加、删除用户和用户组,修改访问权限等。以下将详细介绍用户管理的各个方面。 1. 用户管理工具 在管理用户时,有多种工具可…

作者头像 李华
网站建设 2026/2/5 23:21:52

Bodymovin插件深度解析:从零到精通的终极指南

你是否曾经被After Effects中那些酷炫的动画效果所吸引&#xff0c;却苦于无法将它们完美地呈现在网页或移动应用中&#xff1f;Bodymovin插件就是解决这个痛点的完美答案&#xff01;今天&#xff0c;我将带你全方位了解这个神奇的动画转换工具。 【免费下载链接】bodymovin-e…

作者头像 李华
网站建设 2026/2/7 2:16:05

32、Linux内核管理与虚拟化技术全解析

Linux内核管理与虚拟化技术全解析 1. 内核基础概念 内核是操作系统的核心,负责管理内存、磁盘访问等核心任务,还与系统硬件进行交互。例如,它使Linux具备多任务和多用户支持等标准特性,同时处理与CD - ROM、硬盘等设备的通信。用户通过内核向设备发送访问请求,内核再向设…

作者头像 李华
网站建设 2026/2/3 1:04:26

37、分布式网络文件系统详解

分布式网络文件系统详解 在大型分布式系统(如 Linux 集群)中,分布式网络文件系统发挥着重要作用。它基于 NFS 基本概念和 RAID 技术,能在大型网络的多个主机上实现文件系统,使不同主机共享同一文件系统,提高存储利用率和管理效率。下面将详细介绍几种常见的分布式网络文…

作者头像 李华
网站建设 2026/2/5 22:48:38

学生在教室内编程 程序开发图片素材推荐

《美文美图每日一推》 今天推荐的是关于学生在教室学习编程的图片素材&#xff0c;共有5张内容&#xff0c;如果有宝子们想要商用记得需要获摄图网版权授权©后呦!!!&#x1f3e2;&#xff0c; 当然你也可以在平台检索当前主题:#指尖键盘# #教室角落# #晨光教室# #低头学习…

作者头像 李华