• React中:富文本编辑器(react-quill),自定义上传图片到阿里云


    1. import React, { useState, useEffect, useRef, useMemo } from 'react';
    2. import ReactQuill from 'react-quill';
    3. import { message } from 'antd';
    4. import 'react-quill/dist/quill.snow.css';
    5. import { getTokenApi } from '@/services/user/login';
    6. import { getAliOss } from '@/services/public/api';
    7. import { randomWord } from '@/utils/index';
    8. import { request } from 'umi';
    9. import OSS from 'ali-oss';
    10. const Index: React.FC<any> = (props) => {
    11. const { value, width, height, handleParams } = props;
    12. let refs: any = useRef(null);
    13. const [valueText, setValue] = useState('');
    14. const [widthText, setWidth] = useState('1010px');
    15. const [heightText, setHeight] = useState('300px');
    16. const modules: any = useMemo(
    17. // useMemo: 解决自定义失焦问题
    18. () => ({
    19. toolbar: {
    20. container: [
    21. ['bold', 'italic', 'underline', 'strike'], // 加粗,斜体,下划线,删除线
    22. ['blockquote', 'code-block'], // 引用,代码块
    23. ['link', 'image' /**'video' */], // 上传链接、图片、上传视频
    24. [{ header: 1 }, { header: 2 }], // 标题,键值对的形式;1、2表示字体大小
    25. [{ list: 'ordered' }, { list: 'bullet' }], // 列表
    26. [{ script: 'sub' }, { script: 'super' }], // 上下标
    27. [{ indent: '-1' }, { indent: '+1' }], // 缩进
    28. [{ direction: 'rtl' }], // 文本方向
    29. [{ size: ['small', false, 'large', 'huge'] }], // 字体大小
    30. [{ header: [1, 2, 3, 4, 5, 6, false] }], // 几级标题
    31. [{ color: [] }, { background: [] }], // 字体颜色,字体背景颜色
    32. [{ font: [] }], // 字体
    33. [{ align: [] }], // 对齐方式
    34. ['clean'], // 清除字体样式
    35. ],
    36. handlers: {
    37. image: () => {
    38. imageHandler.call(this, props);
    39. },
    40. },
    41. },
    42. }),
    43. [],
    44. );
    45. // 自定义上传图片
    46. const imageHandler = (action) => {
    47. const input: any = document.createElement('input');
    48. input.setAttribute('type', 'file');
    49. input.setAttribute('accept', 'image/*');
    50. input.click();
    51. input.onchange = async () => {
    52. /*****************************************************ali-oss*****************************************************/
    53. // const client = new OSS({
    54. // region: 'oss-cn-hangzhou',
    55. // accessKeyId: 'LTxxxxxxxxxxxxxxxxxxx',
    56. // accessKeySecret: 'XYxxxxxxxxxxxxxx',
    57. // // stsToken: data.SecurityToken,
    58. // bucket: 'bucketuploadfiles',
    59. // });
    60. const { data } = await getAliOss({});
    61. const client = new OSS({
    62. region: 'oss-cn-shanghai',
    63. accessKeyId: data.AccessKeyId,
    64. accessKeySecret: data.AccessKeySecret,
    65. stsToken: data.SecurityToken,
    66. refreshSTSToken: async () => {
    67. // 向您搭建的STS服务获取临时访问凭证。
    68. const info = await getAliOss({});
    69. return {
    70. accessKeyId: info.data.AccessKeyId,
    71. accessKeySecret: info.data.AccessKeySecret,
    72. stsToken: info.data.SecurityToken,
    73. };
    74. },
    75. expiration: data.Expiration,
    76. // 刷新临时访问凭证的时间间隔,单位为毫秒。
    77. refreshSTSTokenInterval: 300000,
    78. // 填写Bucket名称。
    79. bucket: 'upload-files',
    80. });
    81. try {
    82. const file = input.files[0];
    83. const hide = message.loading('上传中...', 0);
    84. // const fileName = 'ali-oss/upload/images/' + randomWord(false, 50, 50);
    85. const fileName = 'images/' + randomWord(false, 50, 50);
    86. const { name, res, url } = await client.put(fileName, file);
    87. // console.log('上传结果', name, res, url);
    88. if (res.status === 200) {
    89. let quill = refs?.current?.getEditor(); //获取到编辑器本身
    90. const cursorPosition = quill.getSelection().index; //获取当前光标位置
    91. const link = 'httpxxxxxxxxxxxxx.com/' + name; // 图片链接
    92. quill.insertEmbed(cursorPosition, 'image', link); //插入图片
    93. quill.setSelection(cursorPosition + 1); //光标位置加1
    94. hide();
    95. }
    96. } catch (error) {}
    97. /*****************************************************ali-oss*****************************************************/
    98. /****************************************七牛云 (https://xxxxxx)****************************************/
    99. // const { data } = await getTokenApi({});
    100. // const file = input.files[0];
    101. // const formData = new FormData();
    102. // formData.append('key', randomWord(false, 40, 50));
    103. // formData.append('token', data.uploadToken);
    104. // formData.append('file', file);
    105. // const hide = message.loading('上传中...', 0);
    106. // request('https://xxxxxxxxxxxx', {
    107. // method: 'POST',
    108. // data: formData,
    109. // headers: { 'Content-Type': 'application/json' },
    110. // }).then(async (res) => {
    111. // try {
    112. // // console.log('上传结果', res);
    113. // const url = 'https://xxxxxxxxxx.com/' + res.key; // 预览,获取url
    114. // let quill = refs?.current?.getEditor(); //获取到编辑器本身
    115. // const cursorPosition = quill.getSelection().index; //获取当前光标位置
    116. // quill.insertEmbed(cursorPosition, 'image', url); //插入图片
    117. // quill.setSelection(cursorPosition + 1); //光标位置加1
    118. // hide();
    119. // } catch (error) {}
    120. // });
    121. /****************************************七牛云 (https://xxxxxxxx)****************************************/
    122. };
    123. };
    124. const handleHtml = (e) => {
    125. setValue(e);
    126. handleParams(e);
    127. };
    128. const options: any = {
    129. placeholder: '请输入内容...',
    130. theme: 'snow',
    131. readOnly: false, // 是否只读
    132. className: 'ql-editor', //组件要加上(className=“ql-editor”)样式类名,否则空格不回显
    133. onChange: handleHtml,
    134. value: valueText,
    135. modules: modules,
    136. ref: refs,
    137. style: {
    138. width: widthText,
    139. height: heightText,
    140. overflow: 'hidden',
    141. borderBottom: '1px solid #ccc',
    142. },
    143. };
    144. useEffect(() => {
    145. setWidth(width ? width : '1010px');
    146. setHeight(height ? height : '300px');
    147. }, []);
    148. useEffect(() => {
    149. setValue(value ? value : '');
    150. }, [value]);
    151. return (
    152. <div>
    153. <ReactQuill {...options} />
    154. div>
    155. );
    156. };
    157. export default Index;

  • 相关阅读:
    Intel lock前缀指令的屏障能力
    新冠疫情数据建模分析
    numpy array数组 数据增广造成的小问题
    Qt·事件处理机制
    M. 810975(容斥原理)
    VSCode自动分析代码的插件
    AI都那么发达了,我还有必要学习编程吗
    DevOps 环境预测测试中的机器学习
    腾讯云大数据ES Serverless
    2023年10月22日找工作面试交流遇到的基本问题
  • 原文地址:https://blog.csdn.net/qq_36995521/article/details/126156514