react-quill 富文本編輯器插件是一款基礎(chǔ)輕量的編輯器页徐,引入也非常簡單恤左,如下:
import ReactQuill, { Quill } from 'react-quill';
class MyComponent extends React.Component {
constructor(props) {
super(props)
this.state = { text: '' } // You can also pass a Quill Delta here
this.handleChange = this.handleChange.bind(this)
}
handleChange(value) {
this.setState({ text: value })
}
render() {
return (
<ReactQuill value={this.state.text}
onChange={this.handleChange} />
)
}
}
但是巧鸭,編輯器中插入圖片時,編輯器默認(rèn)的處理是將圖片轉(zhuǎn)成base64保存郑叠,提交后端時請求數(shù)據(jù)太大击蹲,給數(shù)據(jù)庫帶來壓力推穷。
因此,進(jìn)行改善娃殖,將圖片先上傳到數(shù)據(jù)庫,使富文本編輯器里插入的img標(biāo)簽,src屬性變成一個鏈接地址郁稍。具體效果見如下圖:
這個方案實現(xiàn)需要如下幾個步驟:
第一步:
在富文本配置的toolbar中增加handler對象桐愉,設(shè)置其image屬性狈究,用于自定義函數(shù)去覆蓋默認(rèn)的方法碎罚,此處為點(diǎn)擊圖片上傳按鈕時拯勉,顯示一個彈框玫鸟。
this.modules={//富文本配置
toolbar:{
container:[
[{ 'font': fonts }],
[{ 'header': [1, 2, 3, 4, 5, 6, false] }],
['bold', 'italic', 'underline','strike', 'blockquote'],
[{ 'color': [] }, { 'background': [] }],
[{'list': 'ordered'}, {'list': 'bullet'}, {'indent': '-1'}, {'indent': '+1'},{ 'align': [] }],
['link', 'image'],
['clean'],
],
handlers: {
'image':this.showUploadBox.bind(this)
}
},
imageDrop: true,
};
//react組件中定義方法
showUploadBox(){
this.setState({
uploadBoxVisible:true
});
}
//react組件render 中return modal結(jié)構(gòu)
<Modal
title="上傳圖片"
visible={this.state.uploadBoxVisible}
onCancel={this.hideUploadBox.bind(this)}
onOk={this.handleUpload.bind(this,this.state.uploadUrl,this.state.file)}
maskClosable={false}
width={500}
>
<div className="top_btn top_btn_upload" >
<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>
第二步:
點(diǎn)擊選擇圖片按鈕時選擇本地一張圖片,具體實現(xiàn)代碼如下:
//組件中定義選擇圖片的方法
selectImage(){
this.refs.uploadInput.click();//點(diǎn)擊modal的html結(jié)構(gòu)中的input標(biāo)簽
}
//如上modal中input標(biāo)簽
<input ref="uploadInput" type='file' accept='image/*'
style={{width:"100px",border:"none",visibility:"hidden"}}
onChange={this.changeImageBeforeUpload.bind(this)}
/>
選擇好圖片后會調(diào)用input的onChange回調(diào)函數(shù),這個回調(diào)函數(shù)可以做一些判斷,其內(nèi)容如下:
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
})
}
第三步:
選擇好圖片后,可以再選擇圖片進(jìn)行替換梅惯,確認(rèn)好后點(diǎn)擊確認(rèn)脚作,進(jìn)行圖片上傳劣针。
/*開始上傳圖片*/
handleUpload(uploadUrl,file){
let this_=this;
/*調(diào)用上傳圖片的封裝方法*/
uploadFunction.uploadForImage(
uploadUrl,
file,
function (response) {//回調(diào)函數(shù)處理進(jìn)度和后端返回值
if (response&&response.code === 200) {
message.success("上傳成功辣苏!");
this_.hideUploadBox();//隱藏彈框
this_.imageHandler(response.data.url);//處理插入圖片到編輯器
}else if (response && response.code !== 200) {
message.error(response.msg)
}
},
localStorage.getItem("access_token"));
}
如上使用的圖片上傳封裝方法如下,將后端返回的數(shù)據(jù)傳輸回調(diào)函數(shù)中:
function uploadForImage(url,data,callback,token) {//data是數(shù)據(jù)列表
console.log('post-請求接口:' + url);
console.log('請求參數(shù):' + data);
let this_=this;
if (!data) {
console.log('未選擇文件');
return;
}
let xhr = new XMLHttpRequest();
let form = new FormData();
form.append('file', data);
xhr.addEventListener('readystatechange',function(e){
console.log(e);
let response=e.target.response?JSON.parse(e.target.response):null;
console.log(response);
if (e.target.readyState===4&&response) {
callback(response);
}
},false);
xhr.open('POST', url, true); // 第三個參數(shù)為async?骏融,異步/同步
xhr.setRequestHeader("accessToken",token);
xhr.send(form);
}
第四步:
處理插入圖片到編輯器,第三步有一個函數(shù)imageHandler(response.data.url),其中凉当,response.data.url為返回的圖片地址,imageHandler內(nèi)容如下:
/*處理圖片插入*/
imageHandler(url){
let quill=this.refs.reactQuillRef.getEditor();//獲取到編輯器本身
const cursorPosition =quill.getSelection().index;//獲取當(dāng)前光標(biāo)位置
quill.insertEmbed(cursorPosition, "image",url, Quill.sources.USER);//插入圖片
quill.setSelection(cursorPosition + 1);//光標(biāo)位置加1
}
到此為止尖阔,功能實現(xiàn)。
可以查看官方文檔了解更多:
react-quill:https://www.npmjs.com/package/react-quill#import-the-component
quill:https://quilljs.com/docs/quickstart/