import React, { useState, useEffect, useRef, useMemo } from 'react';
import ReactQuill from 'react-quill';
import { message } from 'antd';
import 'react-quill/dist/quill.snow.css';
import { getTokenApi } from '@/services/user/login';
import { getAliOss } from '@/services/public/api';
import { randomWord } from '@/utils/index';
import { request } from 'umi';
import OSS from 'ali-oss';
const Index: React.FC<any> = (props) => {
const { value, width, height, handleParams } = props;
let refs: any = useRef(null);
const [valueText, setValue] = useState('');
const [widthText, setWidth] = useState('1010px');
const [heightText, setHeight] = useState('300px');
const modules: any = useMemo(
// useMemo: 解决自定义失焦问题
() => ({
toolbar: {
container: [
['bold', 'italic', 'underline', 'strike'], // 加粗,斜体,下划线,删除线
['blockquote', 'code-block'], // 引用,代码块
['link', 'image' /**'video' */], // 上传链接、图片、上传视频
[{ header: 1 }, { header: 2 }], // 标题,键值对的形式;1、2表示字体大小
[{ list: 'ordered' }, { list: 'bullet' }], // 列表
[{ script: 'sub' }, { script: 'super' }], // 上下标
[{ indent: '-1' }, { indent: '+1' }], // 缩进
[{ direction: 'rtl' }], // 文本方向
[{ size: ['small', false, 'large', 'huge'] }], // 字体大小
[{ header: [1, 2, 3, 4, 5, 6, false] }], // 几级标题
[{ color: [] }, { background: [] }], // 字体颜色,字体背景颜色
[{ font: [] }], // 字体
[{ align: [] }], // 对齐方式
['clean'], // 清除字体样式
handlers: {
image: () => {
imageHandler.call(this, props);
// 自定义上传图片
const imageHandler = (action) => {
const input: any = document.createElement('input');
input.setAttribute('type', 'file');
input.setAttribute('accept', 'image/*');
input.click();
input.onchange = async () => {
/*****************************************************ali-oss*****************************************************/
// const client = new OSS({
// region: 'oss-cn-hangzhou',
// accessKeyId: 'LTxxxxxxxxxxxxxxxxxxx',
// accessKeySecret: 'XYxxxxxxxxxxxxxx',
// // stsToken: data.SecurityToken,
// bucket: 'bucketuploadfiles',
// });
const { data } = await getAliOss({});
const client = new OSS({
region: 'oss-cn-shanghai',
accessKeyId: data.AccessKeyId,
accessKeySecret: data.AccessKeySecret,
stsToken: data.SecurityToken,
refreshSTSToken: async () => {
// 向您搭建的STS服务获取临时访问凭证。
const info = await getAliOss({});
return {
accessKeyId: info.data.AccessKeyId,
accessKeySecret: info.data.AccessKeySecret,
stsToken: info.data.SecurityToken,
expiration: data.Expiration,
// 刷新临时访问凭证的时间间隔,单位为毫秒。
refreshSTSTokenInterval: 300000,
// 填写Bucket名称。
bucket: 'upload-files',
try {
const file = input.files[0];
const hide = message.loading('上传中...', 0);
// const fileName = 'ali-oss/upload/images/' + randomWord(false, 50, 50);
const fileName = 'images/' + randomWord(false, 50, 50);
const { name, res, url } = await client.put(fileName, file);
// console.log('上传结果', name, res, url);
if (res.status === 200) {
let quill = refs?.current?.getEditor(); //获取到编辑器本身
const cursorPosition = quill.getSelection().index; //获取当前光标位置
const link = 'httpxxxxxxxxxxxxx.com/' + name; // 图片链接
quill.insertEmbed(cursorPosition, 'image', link); //插入图片
quill.setSelection(cursorPosition + 1); //光标位置加1
hide();
} catch (error) {}
/*****************************************************ali-oss*****************************************************/
/****************************************七牛云 (https://xxxxxx)****************************************/
// const { data } = await getTokenApi({});
// const file = input.files[0];
// const formData = new FormData();
// formData.append('key', randomWord(false, 40, 50));
// formData.append('token', data.uploadToken);
// formData.append('file', file);
// const hide = message.loading('上传中...', 0);
// request('https://xxxxxxxxxxxx', {
// method: 'POST',
// data: formData,
// headers: { 'Content-Type': 'application/json' },
// }).then(async (res) => {
// try {
// // console.log('上传结果', res);
// const url = 'https://xxxxxxxxxx.com/' + res.key; // 预览,获取url
// let quill = refs?.current?.getEditor(); //获取到编辑器本身
// const cursorPosition = quill.getSelection().index; //获取当前光标位置
// quill.insertEmbed(cursorPosition, 'image', url); //插入图片
// quill.setSelection(cursorPosition + 1); //光标位置加1
// hide();
// } catch (error) {}
// });
/****************************************七牛云 (https://xxxxxxxx)****************************************/
const handleHtml = (e) => {
setValue(e);
handleParams(e);
const options: any = {
placeholder: '请输入内容...',
theme: 'snow',
readOnly: false, // 是否只读
className: 'ql-editor', //组件要加上(className=“ql-editor”)样式类名,否则空格不回显
onChange: handleHtml,
value: valueText,
modules: modules,
ref: refs,
style: {
width: widthText,
height: heightText,
overflow: 'hidden',
borderBottom: '1px solid #ccc',
useEffect(() => {
setWidth(width ? width : '1010px');
setHeight(height ? height : '300px');
}, []);
useEffect(() => {
setValue(value ? value : '');
}, [value]);
return (
<ReactQuill {...options} />
export default Index;
import QuillEditor from 'react-native-quill-editor'
const App = ( ) => {
const onChange = ( html : string ) => {
console . log ( html )
return (
< QuillEditor
style = { { height : 300 } }
options = { {
placeholder : '请赋诗一首...' ,
将mongoDB信息放入dev.js文件
在根目录中键入“ npm install”(下载服务器依赖项)
在客户端目录中键入“ npm install”(下载前端依赖项)
如果您有问题,请随时问我^^
您可以观看此应用程序的教程。
react-native-cn-quill
react-native-cn-quill是react-native的富文本编辑器。 我们已经在Quill Api上创建了这个库。
为什么要羽毛笔
Quill是为现代Web构建的免费,开源WYSIWYG编辑器。 凭借其模块化体系结构和富有表现力的API,可以完全根据需要进行自定义。 阅读更多。
该软件包使用react-native-webview 。 请按照进行安装。
使用npm安装:
npm i react-native-cn-quill
使用纱安装:
yarn add react-native-cn-quill
这是我们组件使用的简单概述。
import React from 'react' ;
import { SafeAreaView , StyleSheet , StatusBar } from 're
React Native Webview Quill.js
Quill.js编辑器和查看器组件,没有用于React Native应用程序的本机代码。 这是一个纯JavaScript组件,基于@zenomaro的react-quill项目( )
在Expo中尝试
npm install --save react-native-webview-quilljs
yarn add react-native-webview-quilljs
import {WebViewQuillEditor, WebViewQuillViewer} from 'react-native-webview-quilljs'
该软件包可用于创建编辑器和查看器
// A Quill.js editor with the standard toolbar
< WebViewQuillJS
后台管理人员操作富文本编辑器上传信息,提供给后端生成信息流!!!
// 引入富文本编辑器样式加载文件
import 'quill/dist/quill.snow.css';
import 'styles/font/quillfont.css';
import { message } from 'antd'; //引入antd样式
import { data } from 'data/upload.js'; //阿里云文件上传的凭证信息 || 具体
Gitlab React-quill:https://github.com/zenoamaro/react-quill
中文文档 Quill:http://doc.quilljs.cn/1409381
官网 Quill:https://quilljs.com/docs/quickstart/
Gitlab Delta:https://github.com/quilljs/delta
图片上传由base64改为走后端接口存储服务端
图片粘贴功能,也走后台接口存储服务端
focus,onb
上文介绍了quill的基础使用,这里主要针对我们不想以图片base64文本格式提交,而是上传服务器获取图片url,以url提交的实现方式以及视频上传的实现
1、隐藏一个input框,使用quill的handler事件实现点击上传到服务器
这种方式可以参考作者再见紫罗兰https://www.cnblogs.com/linxiyue/p/10305047.html
2、由于项目使用饿了么,所以我直接使用其提供的upload组件和Quill自定义定制组合实现上传图片和视频的功能
两个思路方法
$ npm install react-quilljs quill
// If you are using Typescript
$ yarn add -D @types/quill
import React from 'react' ;
import { useQuill } from 'react-quilljs' ;
// or const { useQuill } = require('react-quilljs');
import 'quill/dist/quill.snow.css' ; // Add css for snow th
PayPal:
BTC钱包地址: 3QVyr2tpRLBCw1kBQ59sTDraV6DTswq8Li
ETH钱包地址: 0x394d44f3b6e3a4f7b4d44991e7654b0cab4af68f
LTC钱包地址: MFif769WSZ1g7ReAzzDE7TJVqtkFpmoTyT
自定义单词计数模块
具有自定义字体和格式的自定义工具栏,工具栏位置
显示您的内容格式为html时清理和不清理内容之间的区别
不同内容格式的使用
模板驱动和React形式
代码+语法突出显示
自定义键绑定,例如shift + b表示粗体
动态样式和占位符
切换为只读
气泡工具栏
编辑器初始化后激活格式,例如rtl方向
使用quill quill-view和quill quill-view-html组件呈现quilljs内容
与Angular版本的兼容性
ngx-羽毛笔
在Cloud Firestore作为数据库的React.js中做笔记的网络应用程序。 使用富文本编辑器:React Quill 。
位于index.js中的Firebase API密钥
在启动应用程序之前,用您自己的API密钥替换。
添加Firebase SDK并初始化Firebase: ://firebase.google.com/docs/web/setup。
Create React App入门
该项目是通过引导的。
在项目目录中,可以运行:
npm start
在开发模式下运行应用程序。 打开在浏览器中查看它。
如果您进行编辑,则页面将重新加载。 您还将在控制台中看到任何棉绒错误。
npm test
在交互式监视模式下启动测试运行器。 有关更多信息,请参见关于的部分。
npm run build
构建生产到应用程序build文件夹。 它在生产模式
React-Quill 是Antd推荐使用的富文本编辑器,此文记录一下最近在项目中使用它遇到的一些问题。
首先,大家在百度相关资料时,应当搜索React-Quill,而不是Quill。
github点这里:https://github.com/zenoamaro/react-quill
安装依赖这些就都不说了,只记录干货....
调用示例:
<ReactQuill
them...
富文本编辑器是一种能够让用户在编辑文本时进行格式化的工具。要编写一个完整的富文本编辑器,需要考虑以下几个方面:
1. 用户界面:编辑器需要有一个易于使用和直观的用户界面,包括菜单、工具栏和编辑区。
2. 文本编辑:编辑器需要能够支持常见的文本编辑功能,如插入文本、删除文本、复制和粘贴文本等。同时,编辑器也需要能够支持撤销和重做功能,以便用户在编辑过程中能够轻松地撤销和恢复之前的操作。
3. 文本格式:编辑器需要支持各种文本格式,如加粗、倾斜、下划线、字体、字号等。同时,编辑器还应该支持多种颜色、对齐方式、列表、表格等格式。
4. 图片和多媒体:编辑器需要支持插入图片和其他多媒体元素,例如音频和视频。
5. 导出文本:编辑器需要能够将编辑的文本导出为各种格式,如HTML、Markdown、PDF等,以方便用户在不同的场合下使用。
要实现一个完整的富文本编辑器需要一定的编程技术和知识,可以使用各种编程语言和框架,如JavaScript、React、Angular、Vue.js等。同时,也可以使用现成的编辑器组件库,如Quill、TinyMCE、CKEditor等,这些组件库已经实现了上述功能,可以方便地嵌入到自己的应用程序中。