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集成秀米的示例,我希望我的方法能提供大家一些思路。