[聚合文章] vue项目移植tinymce踩坑

vue.js 2018-01-11 25 阅读

前言

最近因业务需求在项目中嵌入了tinymce这个编辑器,用于满足平台给用户编辑各类新闻内容什么的业务需求,前后也花了不少时间体验和对比了市面上各类开源编辑器。

各大WYSIWYG编辑器的简单比较

UEditor: 因为已经不再维护了,需要大量修改源码,很多都是专门为jsp等服务器渲染项目写的代码需要删除, 然后越删越害怕越删越不敢用,依赖jquery,需要专门用js去parse编辑完成的内容,parse完的内容还可能污染全局css,兼容老浏览器还不错, 但是,我们不怎么考虑兼容IE。所以,告辞。

wangEditor: 中文文档,上手快,依赖jquery,功能少点要花时间去写插件,需要单独为图片上传功能写个接口,老项目忙着上线临时用过,感觉并不适合当前业务这么重的编辑功能于是放弃了。

Quill:api友好, 功能少,需要特定的css去解析文本(这点我不大喜欢),ui好看,适合作为论坛回帖功能使用。

CKEditor: CKEditor目前主流的还是4.x的版本,但是文档看着很瞎眼实在是提不起兴致去配置,草草用了下就放弃了,5.x版本刚从beta结束,需要指定专门的node以及npm版本,虽然功能强大配置灵活ui漂亮不过目前糟糕的兼容性基本是不可能出现在大众视野了。

KingEditor: 丑,不喜欢,不爱用

Draft-js: 知乎最近刚改的文本编辑器就是在draft的基础上开发的,依赖react, 弃。

Medium-editor: 虽然看着感觉很酷炫,但是,不适合我们的业务场景啊, api也简陋可怕。

trix: 嗯,又一个小而美,放弃

Slatereact,放弃

Bootstrap-wysiwygbootstrap, jquery, 放弃

tinymce: 文档好,功能强,bug少,无外部依赖,大家用了都说好,嗯,没错就是它了。

编辑器配置方面只要能看得懂英文耍起来还是比较简单的,适配中碰到的大部分问题都可以通过看文档解决,即便看文档解决不了网上也有大量的文章能告诉你怎么配置能解决。

当然了,主要是我这里需要解决一些别人觉得超简单自己一想都很烦人的需求,比如:

  1. word文档粘贴进来要带格式
  2. 兼容移动端
  3. word文档粘贴进来要正常显示并且还要兼容移动端
  4. 电脑网页里粘贴进来内容要正常显示并且排版还不能乱
  5. 电脑网页拷过来的内容还要兼容到移动端

初始化

因为tinymce的Plugins是按需加载的
为了能先快速上手这个编辑器
就先在vue-cli的index.html中默认塞入一条在线cdn地址

<script src="https://cdn.bootcss.com/tinymce/4.7.4/tinymce.min.js"></script>

后面有机会再写下单独打包的事项,毕竟这货体积还不小。

插入vue组件模板

<template>
  <div>
    <textarea :id= "Id"></textarea>
  </div>
</template>

记得一定要在textarea外面包一层div,不然...你自己试试看就知道了。

组件基础配置

将tinymce通过指定的selector挂载到组件中

<template>
  <div>
    <textarea :id= "Id"></textarea>
  </div>
</template>
<script>
  export default {
    data () {
      const Id = Date.now()
      return {
        Id: Id,
        Editor: null
      }
    },
    props: {
      value: {
        default: '',
        type: String
      },
      config: {
        type: Object,
        default: () => {
          return {
            theme: 'modern',
            height: 300
          }
        }
      }
    },
    mounted () {
      this.init()
    },
    beforeDestroy () {
      // 销毁tinymce
      this.$emit('on-destroy')
      window.tinymce.remove(`$#{this.Id}`)
    },
    methods: {
       init () {
        const self = this
        this.Editor = window.tinymce.init({
          // prop内传入的的config
          ...this.config, 
          // 挂载的DOM对象
          selector: `#${this.Id}`,
          setup: (editor) => {
            // 抛出 'on-ready' 事件钩子
            editor.on(
              'init', () => {
                self.loading = false
                self.$emit('on-ready')
                editor.setContent(self.value)
              }
            )
            // 抛出 'input' 事件钩子,同步value数据
            editor.on(
              'input change undo redo', () => {
                self.$emit('input', editor.getContent())
              }
            )
          }
        })
      }
    }
  }
</script>

好了,组件基本的初始化完成,后面正式开始踩坑之旅

【待续】

注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。