vue-quill-editor 粘贴文字图片及图片上传

问题:
vue-quill-editor富文本编辑器上传图片默认为base64,存入数据库过于庞大,使用 paste 方法 实现图片地址上传。

实现效果图:

NPM
npm install vue-quill-editor --save

 完整代码

<template>
  <div :class="prefixCls">
    <quill-editor v-model="content" ref="myQuillEditor" :content="value" :options="editorOption"
      @blur="onEditorBlur($event)" @focus="onEditorFocus($event)" @ready="onEditorReady($event)"
      @change="onEditorChange($event)">
    </quill-editor>
  </div>
</template>

<script>
import axios from 'axios'
import { quillEditor, Quill } from 'vue-quill-editor'
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
export default {
  name: 'JNPFQuill',
  components: { quillEditor },
  props: {
    prefixCls: {
      type: String,
      default: 'jnpf-editor-quill'
    },
    // 表单校验用字段
    // eslint-disable-next-line
    value: {
      type: String
    },
    placeholder: {
      type: String,
      default: '请输入'
    }
  },
  data() {
    return {
      content: this.value,
      editorOption: {
        modules: {
          toolbar: [
            ["bold", "italic", "underline", "strike"],
            [{ header: [1, 2, 3, 4, 5, 6, false] }],
            [{ size: ["small", false, "large", "huge"] }],
            [{ color: [] }, { background: [] }],
            ["blockquote", "code-block"],
            [{ list: "ordered" }, { list: "bullet" }],
            [{ indent: "-1" }, { indent: "+1" }],
            [{ align: [] }],
            [{ direction: "rtl" }],
            ["clean"],
            ["link", "image"],
          ],
        },
        theme: 'snow',
        placeholder: this.placeholder
      },
      uploadNum:0,// 记录上传次数
      uploadPicList:[] // 图片URL list
    }
  },
  mounted() {
    let quill = this.$refs.myQuillEditor.quill;
    // 粘贴事件
    quill.root.addEventListener("paste", (evt) => {
      const rtf = evt.clipboardData.getData('text/rtf');
      // 提取图片信息
      const hexStrings = this.extractImageDataFromRtf(rtf);
      // 获取base64图片数据
      const base64Images = hexStrings.map((hexObj) => {
        return this.convertHexToBase64(hexObj.hex);
      })
      // 调用上传接口
      for (let i = 0; i < base64Images.length; i++) {
        this.picUpload(`data:image/png;base64,${base64Images[i]}`,base64Images.length)
      }
    })
  },
  methods: {
    base64toFile(dataurl, filename = 'file') {
      let arr = dataurl.split(',')
      let mime = arr[0].match(/:(.*?);/)[1]
      let suffix = mime.split('/')[1]
      let bstr = atob(arr[1])
      let n = bstr.length
      let u8arr = new Uint8Array(n)
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n)
      }
      let file = new File([u8arr], `${filename}.${suffix}`, {
        type: mime
      })
      return file
    },
    /**
     * data: 图片Base64 编码
     * len : 上传图片数量
     */
    async picUpload(data, len) { 
      ++this.uploadNum
      let file = this.base64toFile(data);
      var formData = new FormData();
      formData.append('file', file);
      await axios({
        ContentType:'multipart/form-data',
        url: '/api/file/Uploader',
        method: 'post',
        data: formData
      }).then(res => {
        this.uploadPicList.push(res.data.data.url)
        if (this.uploadNum === len) { 
          setTimeout(() => { 
            this.setResponseUrl(res.data.data.url)
          },500)
        }
      })
    },
    setResponseUrl() {
      const editorDom = this.$refs.myQuillEditor.quill.root;
      const editorImgs = editorDom.querySelectorAll('img[src*="//:0"]');
      // 替换图片Url
      editorImgs.forEach((item, index) => {
        item.src = this.define.comUrl + this.uploadPicList[index];
      })
    },
    /**
     * 
     * rtf中提取图片信息
     * 利用正则从rtf内容中提取到图片的核心信息,得到数组。其中数组中保存的信息有
        {
        type: ‘’, //图片类型
        hex: ‘’ // hex字符串
        }
     * @param {*} rtfData 
     */
    extractImageDataFromRtf(rtfData) {
      if (!rtfData) {
        return [];
      }
      const regexPictureHeader = /{\\pict[\s\S]+?({\\\*\\blipuid\s?[\da-fA-F]+)[\s}]*/
      const regexPicture = new RegExp('(?:(' + regexPictureHeader.source + '))([\\da-fA-F\\s]+)\\}', 'g');
      const images = rtfData.match(regexPicture);
      const result = [];
      if (images) {
        for (const image of images) {
          let imageType = false;

          if (image.includes('\\pngblip')) {
            imageType = 'image/png';
          } else if (image.includes('\\jpegblip')) {
            imageType = 'image/jpeg';
          }

          if (imageType) {
            result.push({
              hex: image.replace(regexPictureHeader, '').replace(/[^\da-fA-F]/g, ''),
              type: imageType
            });
          }
        }
      }
      return result;
    },
    // 讲hex格式转化为base64
    convertHexToBase64(hexString) {
      return btoa(hexString.match(/\w{2}/g).map(char => {
        return String.fromCharCode(parseInt(char, 16));
      }).join(''));
    },
    onEditorBlur(quill) {
      // console.log('editor blur!', quill)
    },
    onEditorFocus(quill) {
      // console.log('editor focus!', quill)
    },
    onEditorReady(quill) {
      // console.log('editor ready!', quill)
    },
    onEditorChange({ quill, html, text }) {
  
      this.$emit("input", this.content);
    },
    insertText(content) {
      let quill = this.$refs.myQuillEditor.quill
      let index = quill.selection.savedRange.index
      quill.insertText(index, content)
      index += content.length
      quill.setSelection(index)
    }
  },
  computed: {
    editor() {
      return this.$refs.myQuillEditor.quill
    }
  },
  watch: {
    value(val) {
      this.content = val
    },
    placeholder(val) {
      this.$set(this.editorOption, 'placeholder', val)
    }
  }
}
</script>

  • 11
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在使用`vue-quill-editor`进行图文粘贴时,复制的图片实际上以base64的形式进行上传。然而,将base64写进数据库并不是一个好的做法。因此,解决思路是将复制的图片上传至服务器,然后将服务器返回的图片地址作为img标签插入到富文本编辑器中,这样就可以正确显示图片了。以下是一个解决思路的代码实例供参考: ```javascript mounted() { let quill = this.$refs.myQuillEditor.quill; quill.root.addEventListener("paste", (evt) => { if (evt.clipboardData && evt.clipboardData.files && evt.clipboardData.files.length) { evt.preventDefault(); [].forEach.call(evt.clipboardData.files, (file) => { if (!file.type.match(/^image\/(gif|jpe?g|a?png|bmp)/i)) { return; } const formData = new FormData(); formData.append("pictureFile", file); makdwnImg(formData) .then((res) => { if (res.data.code == 200) { let quill = this.$refs.myQuillEditor.quill; let length = quill.getSelection().index; quill.insertEmbed(length, "image", res.data.data); quill.setSelection(length + 1); } }) .catch((err) => { console.error(err); }); }); } }, false); }, ``` 通过这段代码,你可以在`vue-quill-editor`中实现图文粘贴图片并正确显示图片。需要注意的是,你需要根据你自己的项目做一些适应性的调整。希望这能帮到你!<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [vue-quill-editor粘贴图片vue-quill-editor复制图片](https://blog.csdn.net/weixin_43131046/article/details/116490735)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值