React-Quill中的圖片上傳及顯示

song279811799發表於2017-12-19

前兩篇文章介紹了在Quill中使用貼圖模組,這篇文章我們說下怎樣把base64編碼的圖片儲存到檔案伺服器,並且用新的地址替換原來的base64。

上文說道在Quill的onChange函式中可以除了普通的DOM,還可以通過editor.getContents()獲取Delta型別的資料。他基本上和json差不多,我們可以對其進行處理,進行圖片的處理。

Quill-Delta的文件:https://quilljs.com/docs/delta/

通過除錯或者看官方文件,可以知道對於圖片型別的資料,結構是:

{
  ops: [{
    // An image link
    insert: {
      image: 'https://quilljs.com/assets/images/icon.png'
    },
  }]
}

對於base64編碼的圖片,那上面的image的值對應的就是base64的一長串資料。

這樣,我們就可以通過遍歷,獲取到所有的base64編碼圖片(注意要篩掉url地址的圖),然後可以轉換成Blob型別,傳給後端儲存在檔案伺服器。下面是轉化格式的程式碼:

convertBase64UrlToBlob = (urlData) => {
    //去掉url的頭,並轉換為byte
    const bytes = window.atob(urlData.split(',')[1]);
    //處理異常,將ascii碼小於0的轉換為大於0
    const ab = new ArrayBuffer(bytes.length);
    const ia = new Uint8Array(ab);
    ia.forEach((i, index) => {
      ia[index] = bytes.charCodeAt(index);
    });
    return new Blob([ia], { type: urlData.split(',')[0].split(':')[1].split(';')[0] });
};

至於上傳的方法有很多,這裡就不詳述了,我用的是reqwest,然後我們拿到圖片的url地址,依次替換Delta中的base64,這樣我們拿到的Delta資料就沒有那麼大了,可以儲存到資料庫中了。注意要轉成string,如JSON.stringify(Delta.ops)

這樣是可以儲存了,但我們要如何在前端中去展現輸入的資料呢?我的辦法是:

首先從後端拿到Delta的string,然後再次利用JSON.parse(Delta)轉回json格式。這樣我們就可以對其進行操作了。如果不需要對資料進行特殊處理,可以直接轉換成DOM結構然後直接渲染到網頁中。

轉Delta到DOM:https://github.com/nozer/quill-delta-to-html
// 引入quill-delta-to-html
const QuillDeltaToHtmlConverter = require('quill-delta-to-html');
// 轉換Delta到html,更多功能請看上面連結中的介紹
const converter = new QuillDeltaToHtmlConverter(delta, {});
const html = converter.convert();

// 利用dangerouslySetInnerHTML渲染DOM,注意要對進行過濾轉換,防止指令碼攻擊
<div dangerouslySetInnerHTML={{__html: `${this.escape(html)}`}}/>

這樣我們就把Delta的資料顯示到了網頁中,如果我們想要對處理,假設對於圖片想加一個點選放大檢視的功能,就可以對Delta進行遍歷,普通內容依照上面的方法顯示,對於圖片則用元件進行封裝。

React圖片檢視元件:https://github.com/fritz-c/react-image-lightbox

功能和使用都很簡單,程式碼如下:

import Lightbox from 'react-image-lightbox';

<div>
    <img
      src={item.insert.image}
      width="300px"
      style={{display: 'block'}}
      alt={HAP.getMessage('圖片載入中...', 'Image Loading...')}
      onClick={() => this.onOpenLightboxChange()}
    />
    {this.state.isOpen ?
      <Lightbox
        mainSrc={item.insert.image}
        onCloseRequest={() => this.onOpenLightboxChange()}
        imageTitle={'images'}
      /> : ''}
</div>

通過onOpenLightboxChange函式控制isOpen來顯示和隱藏lightbox。效果如圖:

這裡寫圖片描述

到這裡,使用Quill富文字編輯器對圖片的一系列處理都說完了。

我還找到了Quill的表情模組,但還沒去研究怎麼在react中使用。

Quill-Emoji:https://github.com/contentco/quill-emoji

相關文章