1、安装
"react-quill": "2.0.0-beta.4",
2、引入组件,如果出现样式问题,需要将node_modules\react-quill\dist\quill.snow.css也一同引入
import ReactQuill, { Quill } from 'react-quill';
3、在表单中使用,其中modules需要配置
<Form.Item style={{ height: 200 }} label="邮件正文" name="richTextContent" className={styles.email_content}> <ReactQuill theme="snow" style={{ height: 160 }} modules={getModules(imageHandler, linkHandler)} key={form1.getFieldValue('richTextContent')} // 解决回显不更新问题 value={form1.getFieldValue('richTextContent')} ref={reactQuillRef} onChange={(value) => form1.setFieldsValue({ richTextContent: value })} onChangeSelection={(selection, source) => { if (['user', 'silent'].includes(source)) { editorRange.current = selection; } }} /> </Form.Item>
4、配置modules,自定义toobar可选择对象配置或者dom挂载的方式,笔者选择了使用对象配置,额外增加linkIcon按钮,只要处理点击事件handleLinkIcon即可。如使用dom挂载需要重写每个按钮功能实现方式
可按官方文档进行配置 quill中文文档
// 富文本配置const getModules = (handleImage: Function, handleLinkIcon: Function) => ({ toolbar: { container: [ [{ header: [1, 2, 3, 4, 5, 6, false] }], // 标题字号,不能设置单个字大小 ['bold', 'italic', 'underline', 'strike', 'blockquote'], // 字体样式 [{ color: [] }, { background: [] }], [{ list: 'ordered' }, { list: 'bullet' }, { indent: '-1' }, { indent: '+1' }, { align: [] }], ['link', 'image', 'linkIcon'] // a链接和图片的显示,自定义linkIcon ], handlers: { image: handleImage, linkIcon: handleLinkIcon } }});
/** quill- 自定义超链接按钮 */ const linkHandler = () => { const editor = reactQuillRef.current.getEditor(); // 获取实例 const range = editorRange.current; const length = editor.getLength(); const cursorPosition = range ? range.index : length - 1; // 获取当前光标位置 const element = `${getQuillLinkElementString()}<span> </span>`; editor.clipboard.dangerouslyPasteHTML(cursorPosition, element); };
/** quill-自定义图片上传 */ const imageHandler = () => { // 创建input标签打开文件选择 const input = document.createElement('input') as HTMLInputElement; input.setAttribute('type', 'file'); input.setAttribute('accept', 'image/*'); input.setAttribute('multiple', 'multiple'); input.click(); input.onchange = async () => { Array.from(input.files).forEach((file: File) => { // 设置图片流 const formData = new FormData(); formData.append('file', file, file.name); const uploadUrl = 'xxxxxxxxxxxxxxxxxxx'; // 上传图片 const xhr = new XMLHttpRequest(); xhr.open('POST', uploadUrl, true); xhr.onreadystatechange = function readyStateChange() { if (xhr.readyState === 4 && xhr.status === 200) { const ret = JSON.parse(xhr.responseText); if (ret.key) { const imageUrl = '上传成功的图片链接'; const currentQuill = reactQuillRef.current.getEditor(); // 获取实例 const cursorPosition = currentQuill.getSelection().index; // 获取当前光标位置 currentQuill.insertEmbed(cursorPosition, 'image', imageUrl); // 插入图片 currentQuill.setSelection(cursorPosition + 1); // 光标位置加1 } } }; xhr.send(formData); xhr.onloadend = () => { dispatch({ type: 'app/spin_hide' }); }; xhr.onerror = () => { message.error('文件上传出错了'); }; }); }; };