vue使用quill编辑器自定义图片上传方法、quill-image-resize-module修改图片、监测粘贴的是图片上传到后端、重新进入编辑器img标签丢失style属性

本文介绍了如何在Vue项目中自定义图片上传功能,包括修改`image.ts`以支持vue-photo-preview预览、使用quill-image-resize-module调整图片尺寸以及解决引用和配置错误。同时,文章还关注了图片上传后处理和编辑器样式问题。
摘要由CSDN通过智能技术生成

1、自定义图片上传

需求:

  • 因为在展示页面使用到了vue-photo-preview组件实现点击图片预览,所以需要修改image.ts进行修改添加预览组件需要的previewpreview-text属性,效果图如下:
    上传图片添加属性
  • 展示页面点击图片预览:
    在这里插入图片描述实现方法:
  1. 到quill到github:https://github.com/quilljs/quill/tree/develop复制image.ts到自己新建的image.js进行改写create,image.ts路径:packages/quill/src/formats/image.ts
    image.js修改处
    	  static create(value) {
    	    const node = super.create(value);
    	    if (typeof value === "string") {
    	      // 保留原来的图片方法
    	      node.setAttribute("src", this.sanitize(value));
    	    } else {
    	      // 自定义图片方法
    	      node.setAttribute("src", value.src);
    	      // 使用了vue-photo-preview,所以添加preview,preview-text这两个属性
    	      node.setAttribute("preview", "1"); //preview相同的为一组,这里所有上传图片为一组
    	      node.setAttribute("preview-text", value.title); //图片名称,预览时显示使用
    	    }
    	    return node;
    	  }
    	```
    
  • image.js完整代码:
    import Quill from "quill";
    let EmbedBlot = Quill.import("formats/image");
    //添加style,解决重进编辑器ima标签丢掉style属性问题
    const ATTRIBUTES = ["alt", "height", "width", "style"];
    
    class Image extends EmbedBlot {
      static blotName = "image";
      static tagName = "IMG";
    
      static create(value) {
        const node = super.create(value);
        if (typeof value === "string") {
          // 保留原来的图片方法
          node.setAttribute("src", this.sanitize(value));
        } else {
          // 自定义图片方法
          node.setAttribute("src", value.src);
          // 使用了vue-photo-preview所以添加preview,preview-text这两个属性
          node.setAttribute("preview", "1"); //preview相同的为一组
          node.setAttribute("preview-text", value.title); //图片名称,预览时显示使用
        }
        return node;
      }
    
      static formats(domNode) {
        return ATTRIBUTES.reduce((formats, attribute) => {
          if (domNode.hasAttribute(attribute)) {
            formats[attribute] = domNode.getAttribute(attribute);
          }
          return formats;
        }, {});
      }
    
      static match(url) {
        return /\.(jpe?g|gif|png)$/.test(url) || /^data:image\/.+;base64/.test(url);
      }
    
      static register() {
        if (/Firefox/i.test(navigator.userAgent)) {
          setTimeout(() => {
            // Disable image resizing in Firefox
            // @ts-expect-error
            document.execCommand("enableObjectResizing", false, false);
          }, 1);
        }
      }
    
      static sanitize(url) {
        return sanitize(url, ["http", "https", "data"]) ? url : "//:0";
      }
    
      static value(domNode) {
        return domNode.getAttribute("src");
      }
    
      format(name, value) {
        if (ATTRIBUTES.indexOf(name) > -1) {
          if (value) {
            this.domNode.setAttribute(name, value);
          } else {
            this.domNode.removeAttribute(name);
          }
        } else {
          super.format(name, value);
        }
      }
    }
    function sanitize(url, protocols) {
      const anchor = document.createElement("a");
      anchor.href = url;
      const protocol = anchor.href.slice(0, anchor.href.indexOf(":"));
      return protocols.indexOf(protocol) > -1;
    }
    
    export default Image;
    
    
  1. vue页面引入image.js
    import Quill from "quill";
    import Image from "./image";
    Quill.register(Image, true);
    
  2. 修改el-upload组件上传成功后回调函数中的quill.insertEmbed()传参,
        handleUploadSuccess(res, file) {
      // 获取富文本组件实例
      let quill = this.Quill;
      // 如果上传成功
      if (res.code === 200) {
        let shiftLength = 1;
        if (this.uploadType == "image") {
          // 插入图片  res.url为服务器返回的图片地址
          quill.insertEmbed(this.lastSelection, "image", {
            src: process.env.VUE_APP_BASE_API + res.data.fileAddress, //上传图片后端返回地址
            title: res.data.originalName, //上传图片名称
          });
        } 
        // 调整光标到最后
        quill.setSelection(this.lastSelection + shiftLength);
        this.$modal.closeLoading();
      } else {
        this.$modal.closeLoading();
        this.$modal.msgError("上传失败,请重试");
      }
    },
    

2、使用quill-image-resize-module插件修改上传的图片尺寸,对齐方式

1. 安装
npm install quill-image-resize-module -- save
2. 引用报错问题解决
  • 报错Cannot read properties of undefined (reading 'impoerts')
    在这里插入图片描述
  • 解决办法:修改vue.config.js,添加配置
    // 20230801添加ts配置
    configureWebpack: {
    // 添加配置解决vue 引入quill - image - resize - module 插件报错
    	plugins: [
          new webpack.ProvidePlugin({
            "window.Quill": "quill/dist/quill.js",
            Quill: "quill/dist/quill.js",
          }),
      ],
    },
    
  • 报错quill Cannot import modules/imageResize. Are you sure it was registered?
    在这里插入图片描述
  • 解决方法:不要在组件内引入插件注册,在main.js内引入并且注册
    javascript // 富文本上传图片调整大小 import Quill from "quill"; import imageResize from "quill-image-resize-module"; // 调整大小组件。 window.Quill = Quill; Quill.register("modules/imageResize", imageResize);
3. 在vue页面添加quill配置项imageResize
	 options: {
        theme: "snow",
        bounds: document.body,
        debug: "warn",
        modules: {
          // 工具栏配置
          toolbar: {
          container: [],
          handlers: {},
          imageResize: {
            //放大缩小
            displayStyles: {
              backgroundColor: "black",
              border: "none",
              color: "white",
            },
            modules: ["Resize", "DisplaySize", "Toolbar"],
            // Resize: 允许缩放、DisplaySize:缩放是显示像素、Toolbar:显示工具栏,用于设置图片居中等样式
          },
          // imageDrop: true, //图片拖拽
        },
        placeholder: "请输入内容",
        readOnly: this.readOnly,
      },

3、重新进入编辑器img标签丢失style属性

  • 在修改的image.js添加‘style’属性即可
    //添加style,解决重进编辑器ima标签丢掉style属性问题
    const ATTRIBUTES = ["alt", "height", "width", "style"];
    

4、监测粘贴的是图片上传到后端

  • 初始化quill编辑器时,添加监听粘贴事件
	// 添加监听事件
	editor.addEventListener("paste", this.handlePaste, true);
    /** 监听粘贴 -如果是图片则将图片上传到服务器*/
    handlePaste(evt) {
      if (
        evt.clipboardData &&
        evt.clipboardData.files &&
        evt.clipboardData.files.length
      ) {
        evt.preventDefault();
        [].forEach.call(evt.clipboardData.files, (file) => {
          // 判断粘贴的是否是图片,不是图片则return
          if (!file.type.match(/^image\/*/i)) {
            return;
          }
          const formData = new FormData();
          formData.append("file", file); //后台上传接口的参数名
          // 获取光标所在位置
          let quill = this.Quill;
          if (!(quill.selection && quill.selection.savedRange)) {
            this.$modal.msgError("上传失败,请重试");
            return;
          }
          this.lastSelection = quill.selection.savedRange.index;
          this.$modal.loading("正在上传文件,请稍候...");
          this.uploadType = "image";
          // 实现上传
          upload(formData)
            .then((res) => {
              // 调用上传成功回调函数
              this.handleUploadSuccess(res);
            })
            .catch((error) => {
              //上传失败回调
              this.handleUploadError();
            });
        });
      }
    },
  • 26
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Vue-Quill-Editor 是一个基于 Quill.js 的富文本编辑器,如果想要在编辑器中上传图片,可以自定义一个上传图片方法。 首先,在 Vue-Quill-Editor 中定义一个上传图片方法: ```javascript <template> <div ref="editor"> </div> </template> <script> import { quillEditor } from 'vue-quill-editor' export default { components: { quillEditor }, methods: { uploadImage(file) { const formData = new FormData() formData.append('file', file) // 发送请求上传文件 // 返回图片地址 return Promise.resolve('https://your-cdn.com/' + file.name) } } } </script> ``` 然后在 `quill-editor` 组件上设置 `:custom-options` 属性,将上传图片方法传递给 Quill.js: ```javascript <quill-editor ref="myQuillEditor" :custom-options="{ modules: { toolbar: [ ['bold', 'italic', 'underline', 'strike'], [{ header: [1, 2, false] }], ['blockquote', 'code-block'], [{ list: 'ordered' }, { list: 'bullet' }], [{ script: 'sub' }, { script: 'super' }], [{ indent: '-1' }, { indent: '+1' }], [{ direction: 'rtl' }], [{ size: ['small', false, 'large', 'huge'] }], [{ header: [1, 2, 3, 4, 5, 6, false] }], [{ color: [] }, { background: [] }], [{ font: [] }], [{ align: [] }], ['clean'], ['link', 'image', 'video'] ], imageDrop: true, imageResize: {}, imageExtend: { loading: true, headers: { 'Authorization': 'Bearer ' + token }, url: 'https://your-api.com/upload/image', method: 'POST', size: 2 * 1024 * 1024, compress: true, convertSize: 1080, format: 'image/jpeg', altKey: true, responseFn: response => { // 返回图片地址 return 'https://your-cdn.com/' + response.data.url } } }, placeholder: '请输入内容', theme: 'snow' }" @ready="onEditorReady" ></quill-editor> ``` 这里主要是设置 `imageExtend` 属性,其中 `url` 属性为上传图片的接口地址, `responseFn` 为上传图片成功后返回的数据处理方法。 最后在 `uploadImage` 方法中发送请求上传图片,并返回图片地址即可。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值