编辑
2024-12-31
React
00

目录

解决与tailwindcss样式冲突
quill
自定义图片上传
[复杂模块]-如何将自定义功能写入quill
[简单模块]-如何将自定义功能写入quill
editor

使用场景建议

  • [1] 需要发布新闻、通知、产品说明文档、上传UI给的图、视频等推荐使用editor 官网wangeditor
  • [2] 需要回复信息、编写论坛内容等,推荐使用quillquill官网

解决与tailwindcss样式冲突

使用editor会有自己的css, 在editor富文本编辑器中正常,预览或者发布之后就失去一些css效果

使用情况
先引入tailwind.css
在引入editor.snow.css

quill

quill中自定义模块

自定义图片上传

TypeScript
import Quill from 'quill'; interface ImageUploadModuleOptions { uploadCallback: (file: File) => Promise<{ img: string; index: number }>; } export default class ImageUploadModule { private quill: Quill; private uploadCallback: (file: File) => Promise<{ img: string; index: number }>; constructor(quill: Quill, options: ImageUploadModuleOptions) { this.quill = quill; this.uploadCallback = options.uploadCallback; const input = document.createElement('input'); input.setAttribute('type', 'file'); input.setAttribute('accept', 'image/*'); input.style.display = 'none'; input.addEventListener('change', this.handleFileChange); this.quill.container.appendChild(input); const toolbar = this.quill.getModule('toolbar') as any; if (toolbar && typeof toolbar.addHandler === 'function') { toolbar.addHandler('uploadImage', () => { input.click(); }); } else { console.error('Toolbar module not found or addHandler is not a function'); } } private handleFileChange = async (e: Event) => { const input = e.target as HTMLInputElement; if (input.files && input.files[0]) { const file = input.files[0]; try { const imgTag: { img: string; index: number } = await this.uploadCallback(file); console.log("imgTag = ", imgTag); if(imgTag){ const srcRegex = /src="([^"]+)"/; const match = imgTag.img.match(srcRegex); const src = match ? match[1] || "" : ''; this.quill.insertEmbed(imgTag.index, 'image', src); // const _timer = setTimeout(() => { // this.quill.focus(); // const range = this.quill.getSelection(true); // console.log("this.quill.root.innerHTML= ", range); // this.quill.setSelection(range.index + 1); // clearTimeout(_timer); // }, 1000) } } catch (error) { console.error('Image upload failed:', error); } } } } export const uploadImageIcon = ` <svg viewbox="0 0 18 18"> <rect class="ql-stroke" height="10" width="12" x="3" y="4"></rect> <circle class="ql-fill" cx="6" cy="7" r="1"></circle> <polyline class="ql-even ql-fill" points="5 12 5 11 7 9 8 10 11 7 13 9 13 12 5 12"></polyline> </svg>`;

相关参数
uploadImage: 对外暴露点击函数以及图片指定module关键字
uploadCallback: 外部自定义上传接口

[复杂模块]-如何将自定义功能写入quill

  • [1] toolbarOptions中添加关键字.如: uploadImage
  • [2] 设置对应图标uploadImageIcon
TypeScript
const uploadImageButton = document.querySelector('.ql-uploadImage'); if (uploadImageButton) { uploadImageButton.innerHTML = uploadImageIcon; }
  • [3] 将模块登记到quillQuill.register('modules/imageUpload', ImageUploadModule as any);
  • [4] 在quill初始化中直接声明imageUpload函数,并调用uploadCallback进行上传

[简单模块]-如何将自定义功能写入quill

  • [1] 设置关键字图标同上
  • [2] 不需要进行模块登记,只需要设置到toolbarOptions即可
  • [3]直接在modules/toolbar/handlers中声明关键字的函数即可,图表点击之后会触发事件.
TypeScript
new Quill("#huaren-editor", { modules: { toolbar: { container: toolbarOptions, handlers: { imageLinks: function(){ changeDialog(true) } } } } } ## 当你需要一个类似于微信回复的富文本框时,可直接如下如下使用 ```TypeScript new Quill(editorRef.current, { theme: 'bubble', modules: { toolbar: false, // 完全移除工具栏 clipboard: { matchers: [[Node.ELEMENT_NODE, function (node: any, delta: any) { delta.ops = delta.ops.map(function (op: any) { return { insert: op.insert } }) return delta; }]] } }, placeholder: '请输入内容...' })

你就能得到一个小巧的input样式的富文本框,可快捷回复

matchers是处理粘贴时将其他地方的背景色复制过来问题, 挺重要的

editor

除了样式问题没啥难度,照着官网撸就行

如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:还是夸张一点

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

还是夸张一点技术专栏 © 2019 - 2023 | 滇ICP备2022001556号
世间情动不过盛夏白瓷梅子汤,碎冰碰壁当啷响。