在vue中使用tinymce__Vue.js
发布于 3 年前 作者 banyungong 2257 次浏览 来自 分享
粉丝福利 : 关注VUE中文社区公众号,回复视频领取粉丝福利

由于公司有个功能,需要用到用到富文本编辑器,最初便选择了简单便捷的wangEditor,可经过一年的使用情况来看,wangEditor已经逐渐无法满足用户各式各样的需求了,几经挑选最终决定换成TinyMCE,以下便是踩过一大堆坑后总结下来的一些经验~

安装TinyMCE

话不多说,直接npm install tinymce冲冲冲

npm install tinymce

TinyMCE默认是英文界面,想使用中文版的别忘了下载汉化包

初始化

引入文件

import tinymce from 'tinymce'

加载tinymce

因为我是直接使用的tinymce而非tinymce-vue,所以html代码中应用textarea组件

html:

<textarea id="uTinymce"></textarea>

js:

tinymce.init({
  selector: '#uTinymce',
  height: 500
})

在init之后,会发现浏览器报Uncaught SyntaxError: Unexpected token '<'的错,检查之后发现是因为theme.js没加载到,因此需要手动引入。后续仍然会有部分文件报这个错误,所以在下面一并引入了

import 'tinymce/themes/silver/theme'
import 'tinymce/icons/default'

引入相关文件后发现,虽然控制台没有报错,但是编辑器无法显示而是一片空白,经过检查之后发现,需要将tinymce中的skins文件夹放至本地引用,于是我就在项目的public文件夹下新建了tinmce文件夹,顺便将之前下载的汉化包也挪了过去

做完这一步后,需要在生成富文本之前,将样式资源的引用地址指向新建的文件夹,并且导入汉化包

window.tinymce.baseURL = `${window.location.origin}/js/tinymce`
tinymce.init({
  selector: '#uTinymce',
  height: 500,
  language_url: 'js/tinymce/langs/zh_CN.js',
  language: 'zh_CN',
})

于是乎~大功告成!

踩坑记录

虽然只是简简单单的生成了富文本编辑器,但是途中踩过的坑可真是不少。。做之前在网上搜索其他人是怎么做的,貌似都是集成了tinymce-vue,但是我做完之后发现tinymce-vue并没有起到作用,所以就给去掉了,以下是遇到的一些奇奇怪怪的问题

1、标签保存自定义属性后换行异常

由于业务的特殊性,我需要在富文本中插入一些带有自定义属性的输入框,类似于<input fieldname='xxx'>这种代码,根据官方api,我直接选择了在init方法中配置valid_elements: '*[*]'属性用于保存所有标签中的所有属性。

却没想到这个配置导致了换行之后,
标签被直接清除的问题

再到api中寻寻觅觅,发现了remove_trailing_brs: false可以使末端节点的
标签保存,然而又双叒叕发现,保存富文本框中的代码时,
标签会自动转换为回车换行符

最后只能投机取巧,将tinymce.js的源码拉到本地,在里面找到了换行时插入
标签的方法emptyBlock

将其中的data-mce-bogus="1"给删掉才得以解决(因为编辑器是根据这句代码将
标签题替换成换行符的)

2、多个路由打开编辑器,切换路由后编辑器加载异常及内容丢失

本来开开心心提测,却又被发现,当多个路由打开富文本编辑器,或者切换路由时,富文本编辑器会变得无法编辑且内容消失等异常问题,解决此问题需要经过以下几点操作:

首先,需要给每个富文本编辑器一个独立的id,我的解决方法是将富文本编辑器作为子组件引入,并通过时间戳生成唯一id传递保存

其次,需要在路由跳转时,将富文本编辑器销毁,并在重新进入页面时再次加载,具体流程可参考https://github.com/PanJiaChen/vue-element-admin中的代码(感谢大佬),具体代码位置在:src-components-Tinymce-index.vue中可以看到

3、粘贴文本清除格式导致重复粘贴

由于业务特殊性,需要对富文本编辑器进行特殊处理,将粘贴进来的内容清除格式,但是给富文本编辑器绑定paste方法后,由于第2点中,对富文本进行重新加载的处理方式导致了刷新页面时,同时存在两个富文本编辑器的情况下,第二个进入的编辑器会绑定两次paste方法,从而导致粘贴进去的文本信息会被粘贴两次,我的解决办法是在第一次进来的时候给编辑器加上标识,若已有标识,便不需要再次绑定paste方法

let doc = document.querySelector(`#${_this.tinymceId}_ifr`).contentWindow.documentlet docTinymce = doc.querySelector('#tinymce')if (docTinymce.className.indexOf('pasteHasBind') === -1) {    //由于activated方法,当多个路由打开了tinymce编辑器时,第二个进来的会加载两次,如果不加以判断,粘贴方法会重复绑定两次,导致粘贴数据异常    docTinymce.addEventListener('paste', function pasteDo(ev) {        //清除被粘贴文本的格式        event.preventDefault()        var text        var clp = (event.originalEvent || event).clipboardData        // 兼容针对于opera ie等浏览器        if (clp === undefined || clp === null) {            text = window.clipboardData.getData('text') || ''            if (text !== '') {                if (window.getSelection) {                    // 针对于ie11 10 9 safari                    var newNode = document.createElement('span')                    newNode.innerHTML = text                    tinyMCE.editors[_this.tinymceId].insertContent(newNode)                } else {                    // 兼容ie10 9 8 7 6 5                    tinyMCE.editors[_this.tinymceId].insertContent(text)                }            }        } else {            // 兼容chorme或hotfire            text = clp.getData('text/plain') || ''            if (text !== '') {                tinyMCE.editors[_this.tinymceId].insertContent(text)            }        }    })    docTinymce.classList.add('pasteHasBind')}

结语

以上便是我在用到TinyMCE时遇到的问题,作为一个总结分享给大家,第一次写文章,可能许多地方表述的不是很清楚,可能有些地方写的还有些问题,希望大家多多指教!

版权声明:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 作者: 叽里呱啦的阿松 原文链接:https://juejin.im/post/6921986236408152077

回到顶部