react-quill 富文本编辑器 ---- 图片处理

   2023-03-08 学习力0
核心提示:import React,{Component} from 'react';import ReactQuill,{ Quill } from 'react-quill';import 'react-quill/dist/quill.snow.css';import { Button ,Modal,message} from 'antd';import MYURLfrom '../api/config';im
import React,{Component} from 'react';
import ReactQuill,{ Quill } from 'react-quill';
import 'react-quill/dist/quill.snow.css';
import { Button ,Modal,message} from 'antd';
import MYURL  from '../api/config';
import { ImageDrop } from 'quill-image-drop-module';
Quill.register('modules/imageDrop', ImageDrop);
class Editer extends Component { constructor(props) { super(props)
this.state = { text: '' } // You can also pass a Quill Delta here this.handleChange = this.handleChange.bind(this) this.selectImage = this.selectImage.bind(this); this.changeImageBeforeUpload = this.changeImageBeforeUpload.bind(this); this.uploadForImage = this.uploadForImage.bind(this); this.imageHandler = this.imageHandler.bind(this); this.showUploadBox = this.showUploadBox.bind(this); this.hideUploadBox =this.hideUploadBox.bind(this); this.handleUpload =this.handleUpload.bind(this); } handleChange(value) { // if (value) ReactQuill.getSelection().dangerouslyPasteHTML(value); this.setState({ text: value }) }; modules={//富文本配置 toolbar:{ container:[ [{ 'header': [1, 2, 3, 4, 5, 6, false] }], ['bold', 'italic', 'underline', 'strike','blockquote'], // toggled buttons ['blockquote', 'code-block'], // [{ 'header': 1 }, { 'header': 2 }], // custom button values [{ 'script': 'sub'}, { 'script': 'super' }], // superscript/subscript [{ 'indent': '-1'}, { 'indent': '+1' }], // outdent/indent [{ 'direction': 'rtl' }], // text direction [{ 'size': ['small', false, 'large', 'huge'] }], // custom dropdown [{'list': 'ordered'}, {'list': 'bullet'}, {'indent': '-1'}, {'indent': '+1'},{ 'align': [] }], [{ 'color': [] }, { 'background': [] }], // dropdown with defaults from theme [{ 'font': [] }], [{ 'align': [] }], ['link', 'image', 'video'], ['clean'], ], handlers: { 'image':this.showUploadBox.bind(this) } }, imageDrop: true, }; showUploadBox(){ this.setState({ uploadBoxVisible:true }); }; hideUploadBox(){ this.setState({ uploadBoxVisible:false }); }; selectImage(){ this.refs.uploadInput.click();//点击modal的html结构中的input标签 }; changeImageBeforeUpload(e){ const file = e.target.files[0]; if (!file) { return; } let src; // 匹配类型为image/开头的字符串 if (file.type==="image/png"||file.type==="image/jpeg") { src = URL.createObjectURL(file); }else{ message.error("图片上传只支持JPG/PNG格式,请重新上传!"); return; } if (file.size/1024/1024>5) { message.error("图片上传大小不要超过5MB,请重新上传!"); return; } this.setState({ src:src, file:file }) console.log('eeeeeee',window) } /*3.开始上传图片*/ handleUpload(){ let this_=this; /*调用上传图片的封装方法*/ if(!this.state.file){ alert('请选择图片!!') }else{ let fileServerAddr = MYURL.fileServer //服务器地址 let file =this.state.file.name let size =this.state.file.size this.uploadForImage(fileServerAddr,file,size,function (response) {//回调函数处理进度和后端返回值 console.log('res----?>',response) if ((response && response.status === 200) ||(response && response.status === "200")) { message.success("上传成功!"); this_.hideUploadBox();//隐藏弹框 console.log("response.data.url???=>",response.data.url) this_.imageHandler(response.data.url);//处理插入图片到编辑器 }else if (response && response.status !== 200) { message.error(response.msg) } }, localStorage.getItem("access_token")); } }; uploadForImage(url,data,size,callback,token) {//data是数据列表 if (!data) { alert('请选择图片!!') console.log('未选择文件'); return; }else{ let xhr = new XMLHttpRequest(); let formdata = new FormData(); formdata.append('file', data); formdata.append('fileSize', size); xhr.onload=() =>{ if(xhr.status === 200 ||xhr.statusn ==='200' ){ let response =JSON.parse(xhr.response) console.log('res====',response) callback(response); } }; // xhr.open('POST', url, true); // 第三个参数为async?,异步/同步 xhr.open('GET', url, true); // 第三个参数为async?,异步/同步 xhr.setRequestHeader("accessToken",token); xhr.send(formdata); } } /*4.处理图片插入*/ imageHandler(url){ if (typeof this.reactQuillRef.getEditor !== 'function') return; const quill = this.reactQuillRef.getEditor() var range = quill.getSelection(); let index = range ? range.index : 0; quill.insertEmbed(index, "image",url, Quill.sources.USER);//插入图片 quill.setSelection(index + 1);//光标位置加1 console.log("quill.getSelection.======",quill.getSelection().index) }; render() { return ( <div style={{maxHeight:"500px"}}> <ReactQuill >.handleChange} theme={"snow"} modules={this.modules} style={{height:"300px"}} /> <Modal title="上传图片" visible={this.state.uploadBoxVisible} onCancel={this.hideUploadBox} onOk={ this.handleUpload } maskClosable={false} width={500} > <div className="ImagaBox" > <div> <Button onClick={this.selectImage.bind(this)} style={{background:"#18ade4",border:"none",color:"#fff"}}> 选择图片 </Button> <input ref="uploadInput" type='file' accept='image/*' style={{width:"100px",border:"none",visibility:"hidden"}} onChange={this.changeImageBeforeUpload.bind(this)} /> </div> <div style={{textAlign:"center",margin:"10px 0"}}> {this.state.src? <img src={this.state.src} alt="" style={{maxWidth:"100%",height:"300px"}}/> : <div style={{background:"#f2f2f2",width:"100%",height:"300px"}}></div> } </div> </div> </Modal> </div> ) } }; export default Editer;

 

 
反对 0举报 0 评论 0
 

免责声明:本文仅代表作者个人观点,与乐学笔记(本网)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
    本网站有部分内容均转载自其它媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,若因作品内容、知识产权、版权和其他问题,请及时提供相关证明等材料并与我们留言联系,本网站将在规定时间内给予删除等相关处理.

  • React实现基于Antd密码强度校验组件示例详解
    React实现基于Antd密码强度校验组件示例详解
    目录引言效果预览组件思想组件开发引言最近在开发 Nest 和 Umi 技术栈的个人项目,在用户管理模块需要用到一个密码强度校验组件,在网上寻找一方资料,没有找到自己想要的,特此自己造轮子!效果预览组件思想既然是密码强度校验,那么强度就必须有个梯度,这
    03-16
  • 03 React快速入门(三)——实现从一个输入框中添加完数据后此输入框内容清除的功能
    03 React快速入门(三)——实现从一个输入框中
    功能描述:      我们在一个输入框输入内容,然后点击添加按钮,此输入框的内容就会添加到页面上,但是此输入框中还存在上次输入的内容,我们想在每次输入添加完成之后,此输入框中的内容就会清除,如图:   实现思路:      我们可以先在输入框上定
    03-08
  • react编译器jsxTransformer,babel
    1.JSX是什么JSX其实是JavaScript的扩展,React为了代码的可读性更方便地创建虚拟DOM等原因,加入了一些类似XML的语法的扩展。2.编译器——jsxTransformerJSX代码并不能直接运行,需要将它编译成正常的JavaScript表达式才能运行,jsxTransformer.js就是这一编
    03-08
  • G2( bizCharts ) React 绘制混合图例
    G2( bizCharts ) React 绘制混合图例
     G2( bizCharts ) React 绘制混合图例,// data-set 可以按需引入,除此之外不要引入别的包import React from 'react';import { Chart, Axis, Tooltip, Geom, Legend, Label } from 'bizcharts';import DataSet from '@antv/data-set';// 下面的代码会被作为
    03-08
  • React-多页面应用 react怎么写页面
    React-多页面应用 react怎么写页面
    1初始化项目npm init create-react-app my-app2.修改indeximport React from 'react';import ReactDOM from 'react-dom';import './index.css';import App from './App';ReactDOM.render(App /, document.getElementById('root')
    03-08
  • react-native start 启动错误解决方法
    ERRORError watching file for changes: EMFILE{"code":"EMFILE","errno":"EMFILE","syscall":"Error watching file for changes:","filename":null}Error: Error watching file for changes: EMFILE
    03-08
  • React兄弟组件通信(发布者-订阅者模式)
    // eventProxy.js'use strict';const eventProxy = {onObj: {},oneObj: {},on: function(key, fn) {if(this.onObj[key] === undefined) {this.onObj[key] = [];}this.onObj[key].push(fn);},one: function(key, fn) {if(this.oneObj[key] === undefined) {thi
    03-08
  • React笔记_(7)_react路由 react路由配置
    路由路由(routing)是指分组从源到目的地时,决定端到端路径的网络范围的进程。路由器当然是作为一个转发设备出现的,主要是转发数据包来实现网络互联。那么react的路由到底指的是什么呢?举个栗子~~~在网页中点击后,从A页面跳到B页面,跳转过程中url发生变
    03-08
  • react-native关闭所有黄色警告 react native st
     将以下这两句话加在index.js(入口文件)中,放在AppRegistry.registerComponent('App', () = App)之前即可1 console.ignoredYellowBox = ['Warning: BackAndroid is deprecated. Please use BackHandler instead.','source.uri should not be an empty str
    03-08
  • react中style的写法 react styles
    div style={{width: 20px; height=30px}}style的写法/div 
    03-08
点击排行