安装
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);
}
}
});
}
}}
/>
}