普洱市网站建设_网站建设公司_ASP.NET_seo优化
2025/12/28 13:08:46 网站建设 项目流程

关于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: '' } } }

下载插件

下载插件

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询