适用于React的富文本编辑器_ReactQuill

13,145 阅读5分钟

ReactQuill

Ant Design官方推荐的富文本编辑器;

github:github地址;

npm地址:npm地址;

本文章记录的是自己学习使用的一个总结,记录的会比较乱一点,可以参照文章:# [深入浅出Quill]Quill基本使用和配置,记录的会比较详细!

ReactQuill的简单使用

  1. 安装ReactQuill

    在项目中引入ReactQuill:

    npm install react-quill --save
    
  2. 在项目的根文件中引入ReactQuill的样式文件;

    // 引入富文本编辑器的样式文件
    import "react-quill/dist/quill.snow.css";
    
  3. 最简单的ReactQuill组件

    import { useState } from "react";
    import ReactQuill from "react-quill";
    
    import "./index.less";
    
    const ReactQuillEditor = () => {
            const [value, setValue] = useState("");
    
            // 剩下参数 delta: DeltaStatic, source: Sources, editor: ReactQuill.UnprivilegedEditor
            const handleChangeValue = (value: string) => {
                    console.log("富文本的值:", value);
                    setValue(value);
            };
    
            return (
                    <div className="react-quill-wrap">
                            <h2 className="title">富文本编辑器</h2>
                            <div className="quill-editor-wrap">
                                    <ReactQuill theme="snow" value={value} onChange={handleChangeValue} />
                            </div>
                    </div>
            );
    };
    
    export default ReactQuillEditor;
    
    

    这样,最简单的富文本编辑器就搭建起来了!,可以在页面上试一试啦!

image.png

ReactQuill的配置

属性

theme

snow

主题属性,默认或者不传采用的是"snow",就是上面的一个展示效果;

bubble

引入样式文件:

// 引入富文本编辑器的样式文件
import "react-quill/dist/quill.bubble.css";

出来的效果:

image.png

这两个主题目前在我看来就是带不带工具栏的区别;

Custom ToolBar(自定义工具栏)

工具栏的具体配置展示可以参照ReactQuill的文档:quilljs.com/docs/module…;

在组件上通过modules,formats属性来制定;

我们可以通过modules属性中的toolbar来控制工具栏的具体配置;

参照代码:

import { useState } from "react";
import ReactQuill from "react-quill";
import { debounce } from "lodash";

import "./index.less";

const ReactQuillEditor = () => {
	const [value, setValue] = useState("");

	// 自定义工具栏
	const modules = {
		// 方式1: 可以是简单的一维数组配置
		// toolbar: ["bold", "italic", "underline", "strike", "blockquote"]
		// 方式2: 可以配置二维数组,进行多个选项的配置
		toolbar: [
			["bold", "italic", "underline", "strike", "blockquote"],
			// 或者针对某一个配置项的key值,进行配置
			[{ header: [1, 2, false] }],
			[{ list: "ordered" }, { list: "bullet" }, { indent: "-1" }, { indent: "+1" }],
			["link", "image"],
			["clean"],
			[{ size: ["small", false, "large", "huge"] }],
			[{ color: [] }, { background: [] }]
		]
		// 方式3: 可以自己指定工具栏的容器
		// toolbar: "#rq-toolbar"
	};

	// 剩下参数 delta: DeltaStatic, source: Sources, editor: ReactQuill.UnprivilegedEditor
	const handleChangeValue = debounce((value: string) => {
		console.log("富文本的值:", value);
		setValue(value);
	}, 500);

	return (
		<div className="react-quill-wrap">
			<h2 className="title">富文本编辑器</h2>
			<div className="quill-editor-wrap">
				{/* 自定义的工具栏 */}
				<div className="quill-editor-toolbar" id="rq-toolbar">
					<button className="ql-bold"></button>
					<button className="ql-italic"></button>
				</div>
				<ReactQuill theme="snow" modules={modules} value={value} onChange={handleChangeValue} />
			</div>
		</div>
	);
};

export default ReactQuillEditor;

这里主要写了三种赋值方式;

modules

该属性可以控制工具栏的配置,但是github.com/zenoamaro/r… 这里的介绍中有说,不建议使用ReactQuill的toolbar,建议我们使用Quill的toolbar;

formats

children/自定义编辑区域

如果我们没有指定编辑区域,会默认帮我们生成一个div;

<ReactQuill
    theme="snow"
    // modules={modules}
    value={value}
    onChange={handleChangeValue}
    >
    <div className="editor-area"></div>
</ReactQuill>

这样我们就可以设置编辑区域的样式了

显示效果:

image.png

defaultValue

这里有个注意的地方,如果绑定了value属性,在设置defaultValue会不起作用,建议直接将初始值赋给value;

bounds

Quill 用来限制弹出窗口位置的选择器或 DOM 元素。 默认为 document.body

preserveWhitespace

如果为 true,则 pre 标签将用于编辑器区域,而不是默认的 div 标签。 这可以防止 Quill 在粘贴时折叠连续的空白。 相关问题。

常见属性

以下比较常用的属性就不再描述了:

readOnly
placeholder
style
classname
tabIndex

事件

onChange(content, delta, source, editor)

通过onChange事件可以拿到四个参数:

  • content:编辑器的 HTML 内容;
  • delta:表示更改的增量对象;
  • source:更改源;
  • editor:编辑器访问器(如 getHTML())的只读代理;(请勿将此增量对象用作值,因为它会导致循环。 请改用 editor.getContents())

onChangeSelection(range, source, editor)

在组件上绑定试了一下:

  • 当输入框内容发生变化的时候,它会返回当前发生变化的文本的下标;
  • 当我们选中编辑器某一段内容的时候,返回选中范围的文本的开始位置的下标;

onFocus(range, source, editor)

在编辑区域获取焦点的时候触发,同时会将当前光标的位置返回;

与onChangeSelection事件的区别在于,它只在编辑器获得焦点的时候触发一次,而onChangeSelection是光标在编辑区每次移动都会触发;

onBlur(previousRange, source, editor)

失去焦点的时候,会将失去焦点之前的光标位置返回; 我发现这个时候onChangeSelection事件也会执行,但是返回的是null;

键盘事件

下面这几个事件就不再描述了:

  1. onKeyPress
  2. onKeyDown
  3. onKeyUp

方法

获取到编辑器的ref引用可以使用的方法:

focus()

blur()

getEditor()

返回当前编辑器的Quill实例,但是尽量避免直接操作实例对象更改值;

makeUnprivilegedEditor

可以通过它获取getLength(),getText(),getHTML(),getContents(),getSelection(),getBounds();

但是文档中不建议使用!!!

学习时的代码:

import { useRef, useState } from "react";
import ReactQuill, { Quill } from "react-quill";
import { debounce } from "lodash";

import "./index.less";
import { Button } from "antd";

const ReactQuillEditor = () => {
	const [value, setValue] = useState("初始值");
	const editorRef = useRef(null);

	// 自定义工具栏
	const modules = {
		// 方式1: 可以是简单的一维数组配置
		// toolbar: ["bold", "italic", "underline", "strike", "blockquote"]
		// 方式2: 可以配置二维数组,进行多个选项的配置
		// 或者针对某一个配置项的key值,进行配置
		toolbar: [
			// 默认的
			// [{ header: [1, 2, 3, false] }],
			// ["bold", "italic", "underline", "link"],
			// [{ list: "ordered" }, { list: "bullet" }],
			// ["clean"]
			// 掘金的富文本编辑器
			"bold",
			"italic",
			"underline",
			{ header: 1 },
			{ header: 2 },
			"blockquote",
			"code-block",
			"code",
			"link",
			{ list: "ordered" },
			{ list: "bullet" },
			"image"
		]
		// 方式3: 可以自己指定工具栏的容器
		// toolbar: "#rq-toolbar"
	};

	// 剩下参数 delta: DeltaStatic, source: Sources, editor: ReactQuill.UnprivilegedEditor
	const handleChangeValue = debounce((value: string, delta: any, source: any, editor: any) => {
		console.log("handleChangeValue-->", value, delta, source, editor);
		setValue(value);
	}, 500);

	const handleGetEditor = () => {
		console.log("编辑器实例:", editorRef?.current?.getEditor());
	};

	return (
		<div className="react-quill-wrap">
			<h2 className="title">富文本编辑器</h2>
			<div className="quill-editor-wrap">
				{/* 自定义的工具栏 */}
				{/* <div className="quill-editor-toolbar" id="rq-toolbar">
					<button className="ql-bold"></button>
					<button className="ql-italic"></button>
				</div> */}
				<ReactQuill
					theme="snow"
					// className="editor-area"
					style={{ borderRadius: "10px" }}
					placeholder="我是富文本编辑器的提示信息"
					preserveWhitespace
					// defaultValue="<strong>我是默认值</strong>"
					// readOnly
					modules={modules}
					ref={editorRef}
					value={value}
					onChange={handleChangeValue}
					onChangeSelection={range => {
						console.log("onChangeSelection--->", range);
					}}
					onFocus={range => {
						console.log("onFocus--->", range);
					}}
					onBlur={previousRange => {
						console.log("onBlur--->", previousRange);
					}}
				/>
				{/* 自定义编辑区域 */}
				{/* <h2 className="title">自定义编辑区域</h2> */}
				{/* <ReactQuill
					theme="snow"
					// modules={modules}
					value={value}
					onChange={handleChangeValue}
				>
					<div className="editor-area"></div>
				</ReactQuill> */}
			</div>
			<Button onClick={handleGetEditor}>获取编辑器实例</Button>
		</div>
	);
};

export default ReactQuillEditor;