##react中quill的使用
近期使用由于项目需要一款富文本编辑框,本来打算试着使用drift.js写一款富文本编辑器。但由于时间比较紧急最后选择引用第三方插件,在众多富文本插件中初步选择了Quill和CKEditor5,最后选择了简单便捷的Quill。下面是目录:
通过npm install quill 引入最新的quill插件;
项目中引入:
import Quill from 'quill';
import 'quill/dist/quill.snow.css';
在componentDidMount进行初始化:
const textbox = this.refs.textarea;
const options = {
debug: 'warn',
modules: {
toolbar: toolbarOptions,
},
placeholder: '请输入文本...',
readOnly: false,
theme: 'snow'
};
editor = this.editor = new Quill(textbox, options);
const {answer} = this.props.problemDetails;
if (answer) editor.clipboard.dangerouslyPasteHTML(answer);
editor.on('text-change', this.handleChange.bind(this));
answer是赋予富文本的初始值;
options为配置项,debug为在console中打印信息的时期,可供选择的有‘debug’,‘warn’,‘log’和‘info’;toolbar选为TRUE是指toolbar选用默认功能;readOnly指是否可编辑;theme有‘snow’和‘bubble’两种选择,分别是toolbar部分是否显示。
var toolbarOptions = [
['bold', 'italic', 'underline', 'strike'], // toggled buttons
['blockquote', 'code-block'],
[{ 'header': 1 }, { 'header': 2 }], // custom button values
[{ 'list': 'ordered'}, { 'list': 'bullet' }],
[{ 'script': 'sub'}, { 'script': 'super' }], // superscript/subscript
[{ 'indent': '-1'}, { 'indent': '+1' }], // outdent/indent
[{ 'direction': 'rtl' }], // text direction
[{ 'size': ['small', false, 'large', 'huge'] }], // custom dropdown
[{ 'header': [1, 2, 3, 4, 5, 6, false] }],
[{ 'color': [] }, { 'background': [] }], // dropdown with defaults from theme
[{ 'font': [] }],
[{ 'align': [] }],
['clean'] // remove formatting button
];
这里大家可以参考官方文档进行配置,配置大家需要的toolbar.我这里精简了许多。
由于quill是老外开发的,所以它的toolbar提示也是中文。这里我已font为例进行自定义配置。
首先在全局样式中引入字体样式
/*font汉化*/
.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 {
content: "宋体";
font-family: "SimSun";
}
.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 {
content: "黑体";
font-family: "SimHei";
}
.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 {
content: "微软雅黑";
font-family: "Microsoft YaHei";
}
.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 {
content: "楷体";
font-family: "KaiTi";
}
.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 {
content: "仿宋";
font-family: "FangSong";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Arial]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Arial]::before {
content: "Arial";
font-family: "Arial";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Times-New-Roman]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Times-New-Roman]::before {
content: "Times New Roman";
font-family: "Times New Roman";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=sans-serif]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=sans-serif]::before {
content: "sans-serif";
font-family: "sans-serif";
}
.ql-font-SimSun {
font-family: "SimSun";
}
.ql-font-SimHei {
font-family: "SimHei";
}
.ql-font-Microsoft-YaHei {
font-family: "Microsoft YaHei";
}
.ql-font-KaiTi {
font-family: "KaiTi";
}
.ql-font-FangSong {
font-family: "FangSong";
}
.ql-font-Arial {
font-family: "Arial";
}
.ql-font-Times-New-Roman {
font-family: "Times New Roman";
}
.ql-font-sans-serif {
font-family: "sans-serif";
}
然后在把样式引入到quill中
const fonts = ['SimSun', 'SimHei','Microsoft-YaHei','KaiTi','FangSong','Arial','Times-New-Roman','sans-serif'];
var Font = Quill.import('formats/font');
Font.whitelist = fonts; //将字体加入到白名单
Quill.register(Font, true);
然后再将toolbarOptions中的font换调
var toolbarOptions = [
['bold', 'italic', 'underline', 'strike'], // toggled buttons
['blockquote', 'code-block'],
[{ 'header': 1 }, { 'header': 2 }], // custom button values
[{ 'list': 'ordered'}, { 'list': 'bullet' }],
[{ 'script': 'sub'}, { 'script': 'super' }], // superscript/subscript
[{ 'indent': '-1'}, { 'indent': '+1' }], // outdent/indent
[{ 'direction': 'rtl' }], // text direction
[{ 'size': ['small', false, 'large', 'huge'] }], // custom dropdown
[{ 'header': [1, 2, 3, 4, 5, 6, false] }],
[{ 'color': [] }, { 'background': [] }], // dropdown with defaults from theme
[{ 'font': fonts }],
[{ 'align': [] }],
['clean'] // remove formatting button
];
这样就实现了字体的自定义,其他配置均可参考。
imageHandle = (file) => {
/*const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
message.error('图片大小不能超过2M');
}else{
const base64 = getBase64Image(file);
}*/
const reader = new FileReader();
const AllowImgFileSize = 2100000; //上传图片最大值(单位字节)( 2 M = 2097152 B )超过2M上传失败
let imgUrlBase64;
if (file) {
//将文件以Data URL形式读入页面
imgUrlBase64 = reader.readAsDataURL(file);
reader.onload = function (e) {
//var ImgFileSize = reader.result.substring(reader.result.indexOf(",") + 1).length;//截取base64码部分(可选可不选,需要与后台沟通)
if (AllowImgFileSize != 0 && AllowImgFileSize < reader.result.length) {
message.error( '上传失败,请上传不大于2M的图片!');
return;
}else{
//执行上传操作
/* console.log(reader.result);*/
const range = editor.getSelection();
if (range) {
editor.insertEmbed(range.index, 'image',""+reader.result); //将上传好的图片,插入到富文本的range.index(当前光标处)
}else{
editor.insertEmbed(0, 'image',""+reader.result);
}
}
}
}
}
shang