富文本编辑器 之 react-quill 踩过的坑~

 安装

npm install react-quill --save

引入

import ReactQuill, { Quill } from 'react-quill';
import 'react-quill/dist/quill.snow.css'; // 富文本样式

modules配置

 // 富文本编辑配置
  const modules = React.useMemo(
    () => ({
      toolbar: {
        container: [
          ['bold', 'italic', 'underline', 'strike'], // 加粗,斜体,下划线,删除线
          ['blockquote', 'code-block'], // 字体样式
          ['link', 'image'], // 上传图片、上传视频
          [{ list: 'ordered' }, { list: 'bullet' }], // 有序列表,无序列表
          [{ script: 'sub' }, { script: 'super' }], // 下角标,上角标
          // [{ indent: '-1' }, { indent: '+1' }], // 缩进
          [{ align: [] }], // 居中
          // [{ 'size': ['small', false, 'large', 'huge'] }],  // custom dropdown
          [{ color: [] }, { background: [] }], // 文字颜色、背景颜色选择
          [{ direction: 'rtl' }], // 文字输入方向
          [{ header: [1, 2, 3, 4, 5, 6, false] }], // 标题
          [{ font: fontArr }], // 自定义字体
          [{ lineheight: ['1', '1.5', '1.75', '2', '3', '4', '5'] }], // 自定义行高
          ['clean'], // 清除样式
        ],
        handlers: {
          image: () => showUploadBox(), // 自定义图片上传
          lineheight: (value: any) => {  // 自定义行高
            if (value) {
              let quill = reactQuillRef.current.getEditor();
              quill.format("lineHeight", value)
            }
          }
        },
      },
      clipboard: {
        matchers: [[]],
      },
      imageResize: {
        // 调整图片尺寸
        displayStyles: {
          border: 'none',
        },
        modules: ['Resize', 'DisplaySize', 'Toolbar'],
      },
    }),
    [],
  );

自定义字体 

// 自定义quill编辑器的字体
let fontArr = ['SimSun', 'SimHei', 'Microsoft-YaHei', 'KaiTi', 'FangSong']; // 这里的顺序注意一下
let Font = Quill.import('formats/font');
Font.whitelist = fontArr; // 将字体加入到白名单 ,这里可在 /formats/fonts.js 中了解
Quill.register(Font, true);

字体样式需导入

      .ql-snow .ql-picker.ql-font .ql-picker-label[data-value='SimSun']::before,
      .ql-snow .ql-picker.ql-font .ql-picker-item[data-value='SimSun']::before {
        font-family: 'SimSun' !important;
        content: '宋体';
      }

      .ql-snow .ql-picker.ql-font .ql-picker-label[data-value='SimHei']::before,
      .ql-snow .ql-picker.ql-font .ql-picker-item[data-value='SimHei']::before {
        font-family: 'SimHei';
        content: '黑体';
      }

      .ql-snow .ql-picker.ql-font .ql-picker-label[data-value='Microsoft-YaHei']::before,
      .ql-snow .ql-picker.ql-font .ql-picker-item[data-value='Microsoft-YaHei']::before {
        font-family: '微软雅黑';
        content: '微软雅黑';
      }

      .ql-snow .ql-picker.ql-font .ql-picker-label[data-value='KaiTi']::before,
      .ql-snow .ql-picker.ql-font .ql-picker-item[data-value='KaiTi']::before {
        font-family: 'KaiTi' !important;
        content: '楷体';
      }

      .ql-snow .ql-picker.ql-font .ql-picker-label[data-value='FangSong']::before,
      .ql-snow .ql-picker.ql-font .ql-picker-item[data-value='FangSong']::before {
        font-family: 'FangSong';
        content: '仿宋';
      }

      /*  设置每个字体的css字体样式 */
      .ql-font-SimSun {
        font-family: 'SimSun';
      }

      .ql-font-SimHei {
        font-family: 'SimHei';
      }

      .ql-font-Microsoft-YaHei {
        font-family: '微软雅黑';
      }

      .ql-font-KaiTi {
        font-family: 'KaiTi';
      }

      .ql-font-FangSong {
        font-family: 'FangSong';
      }

自定义行高

// 自定义行高
const Parchment = Quill.import('parchment');
const lineHeightStyle = new Parchment.Attributor.Style('lineHeight', 'line-height', {
  scope: Parchment.Scope.INLINE,
  whitelist: ["1", "1.5", "1.75", "2", "3", "4", "5"],
});
Quill.register({ 'formats/lineHeight': lineHeightStyle }, true);

行高样式需引入

// 自定义行高
      .ql-snow .ql-picker.ql-lineheight .ql-picker-label[data-value='1']::before,
      .ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value='1']::before {
        content: '1';
      }

      .ql-snow .ql-picker.ql-lineheight .ql-picker-label[data-value='1.5']::before,
      .ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value='1.5']::before {
        content: '1.5';
      }

      .ql-snow .ql-picker.ql-lineheight .ql-picker-label[data-value='1.75']::before,
      .ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value='1.75']::before {
        content: '1.75';
      }

      .ql-snow .ql-picker.ql-lineheight .ql-picker-label[data-value='2']::before,
      .ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value='2']::before {
        content: '2';
      }

      .ql-snow .ql-picker.ql-lineheight .ql-picker-label[data-value='3']::before,
      .ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value='3']::before {
        content: '3';
      }

      .ql-snow .ql-picker.ql-lineheight .ql-picker-label[data-value='4']::before,
      .ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value='4']::before {
        content: '4';
      }

      .ql-snow .ql-picker.ql-lineheight .ql-picker-label[data-value='5']::before,
      .ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value='5']::before {
        content: '5';
      }

      .ql-snow .ql-picker.ql-lineheight {
        width: 70px;
      }

调整图片尺寸

import ImageResize from 'quill-image-resize-module-react';

// 使用前需注册
Quill.register('modules/imageResize', ImageResize); // 注册图片缩放

组件使用

const ReactQuillContent: React.FC = () =>{
    const reactQuillRef = useRef<any>(null);
    const [contentCn, setContentCn] = useState(''); // 富文本内容
    // 组件使用
    <ReactQuill
        ref={reactQuillRef}
        placeholder="请输入..."
        theme="snow"
        modules={modules}
        value={contentCn}
        onChange={(content, delta, source, editor) => {
          // 如下代码可解决 图片粘贴后为base64,上传至服务器文件过大,所以需要将base64格式图片进行转换,具体方法如下:
          let delta_ops = delta.ops;
          let quilContent = editor.getContents();
          if (delta_ops && delta_ops.length) {
           quilContent?.ops?.map((item) => {
              if (item.insert) {
                 let imgStr = item.insert.image;
                 if (imgStr && imgStr?.includes('data:image/png;base64')) {
                   let file = base64toFile(imgStr);
                   const formData = new FormData();
                   formData.append('file', file);
                   // 调用文件上传接口-将二进制图片文件上传至服务器,服务器返回一个图片地址
                   uploadImage(formData).then((res) => {
                      // 我这里的 res.data是图片的url
                      if (res.errorMessage === '成功') {
                        item.insert.image = res.data;
                        setContentCn(quilContent);
                      } else {
                        message.error(res.errorMessage);
                      }
                   });
                 } else {
                    setContentCn(content);
                 }
              }
             });
           }
          }}
     />
}

最终效果

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值