一文教你在quill编辑器中集成秀米编辑器和135编辑器

1:问题&需求

大家知道,quill会自动过滤掉秀米和135编辑器文章里面的section之类的样式,导致复制进去的文章排版根本不能看。秀米官网声明只支持ueditor内核的编辑器内核。如果项目里用的编辑器不是ueditor内核的,而客户一定要秀米的功能,咋整?换编辑器?怼客户?换编辑器是不可能换的,这辈子都不可能换的。怼客户又不会,只能自己开发一个这样子。

下面直接上成品,有兴趣的继续往下看,没兴趣直接拷贝仓库研究。

示例地址: 在线预览

github仓库:https://github.com/font-size/quill-xiumi-135

本文教你如何在vue项目中使用quill编辑器集成秀米编辑器和135编辑器。

  秀米样式

  直接复制到quill的样式

 

1:解决思路

quill中有自定义的blot,可以防止过滤掉自己不想过滤的内容。地址 https://github.com/quilljs/parchment#blots 

  在项目里自定义个blot.js

export default function (Quill) {
  // 引入源码中的BlockEmbed
  const BlockEmbed = Quill.import('blots/block/embed');
  // 定义新的blot类型
  class AppPanelEmbed extends BlockEmbed {
    static create(value) {
      const node = super.create(value);
      // node.setAttribute('contenteditable', 'false');
      // node.setAttribute('width', '100%');
      //   设置自定义html
      node.innerHTML = this.transformValue(value)
      return node;
    }

    static transformValue(value) {
      let handleArr = value.split('\n')
      handleArr = handleArr.map(e => e.replace(/^[\s]+/, '')
        .replace(/[\s]+$/, ''))
      return handleArr.join('')
    }

    // 返回节点自身的value值 用于撤销操作
    static value(node) {
      return node.innerHTML
    }
  }
  // blotName
  AppPanelEmbed.blotName = 'AppPanelEmbed';
  // class名将用于匹配blot名称
  AppPanelEmbed.className = 'rich-innerHtml';
  // 标签类型自定义
  AppPanelEmbed.tagName = 'div';
  Quill.register(AppPanelEmbed, true);
}

  接着在vue页面引入

// 引入原始组件
  import * as Quill from 'quill'
  // 引入核心样式和主题样式
  import 'quill/dist/quill.core.css'
  import 'quill/dist/quill.snow.css'
  // 引入自定义blot
  import blotSelect from './components/blot'
  blotSelect(Quill)

  通过自定义blot只完成了一步,即开辟了一个不会被quill过滤的通道,那如何让秀米代码走这里呢?

我们打开秀米官网,找到页面底部的"第三方对接秀米",点击打开后进入 https://ent.xiumi.us/ue/ 

  下载这个页面

 

 

 看页面代码,秀米自己包了一层iframe,通过层层传递message的方式,向上传递数据,最后被ueditor接收到,然后插入到编辑器里。

那么我们手动改,改成quiill接收,并通过我们之前自定义的blot通道插入内容即可。

  xiumi-ue-dialog-v5.html 页面js代码修改

    var parent = window.parent; // quill实例 修改1
    var xiumi = document.getElementById('xiumi');
    var xiumi_url = window.location.protocol + "//xiumi.us";
    xiumi.onload = function () {
        console.log("postMessage");
        xiumi.contentWindow.postMessage('ready', xiumi_url);
    };
    document.addEventListener("mousewheel", function (event) {
        event.preventDefault();
        event.stopPropagation();
    });
    window.addEventListener('message', function (event) {
        if (event.origin == xiumi_url) {
            parent.setRichText(event.data) // 插入内容 修改2
            // editor.execCommand('insertHtml', event.data);
            // dialog.close();
        }
    }, false);

  

数据传输功能已经完成,现在来完善整个流程。

秀米需要弹出框,我们下载了antdUi(你也可以用elementUi),使用里面的modal组件。

  app.vue

  <a-modal v-model="visible" title="秀米" width="90%" :footer="null" :maskClosable="false" :centered="true" :keyboard="false">
      <div v-if="visible">
        <iframe src="./pluging/xiumi-ue-dialog-v5.html" frameborder="0" width="100%" :height="(fullheight - 150)+'px'" id="xiumiIframe"></iframe>
      </div>
    </a-modal>

  app.vue 相关js

    setRichText(e) {
      const index = this.selection?this.selection.index: 0
      this.quill.insertEmbed(index ||  0, 'AppPanelEmbed', e)
      this.visible = false
      this.visible2 = false
    },
    showModal() {
      this.visible = true
    },

注意,需要把 setRichText方法绑定到window上,这样在xiumi-ue-dialog-v5.html 页面才能通过方法接收到message后插入到quill里。

  mounted () {
    // 初始化编辑器
    this._initEditor()
    window.setRichText = this.setRichText
  },

4:效果图

 

 

 

 

4:总结

这里有几个坑,quill直接过滤了“脏html”,没有像ueditor可以进行配置,开始对它简直束手无策。然后秀米官网说只支持ueditor,我通过qq群咨询了秀米官方人员,也明确告诉我只支持ueditor,没有支持其他编辑器的计划。

但客户那边明确要秀米之类的编辑器,在项目中也不好换编辑器,只能硬着头皮看源码。整个数据传递过程中,只需要改动最后一步,既最终把message插入到编辑器的步骤,把ueditor转换成quill。拿到data后,再通过我们自定义的quill里的blot新通道,避免过滤样式,最终成功插入秀米!

网上目前没有相关quill集成秀米的示例,我希望我的方法能提供大家一些思路。

posted @ 2020-08-19 11:55  江借时  阅读(1112)  评论(0编辑  收藏  举报