antd + vue2 + vue-quill-editor实现富文本+粘贴图片+图片大小设置

项目记录,思路其实就是监听粘贴事件,监听到用户粘贴调用上传图片接口,之后获取鼠标位置,将图片插入到指定位置就行

使用需要看下代码标蓝的地方,按需替换

安装


npm install vue-quill-editor --save
cnpm i quill-image-resize-module --save 
控制图片大小的

引入后的报错问题

处理:
在build文件夹下的webpack.base.conf.js新增如下代码

module.exports = {
    plugins: [
            new webpack.ProvidePlugin({
                // 在这儿添加下面两行
                'window.Quill': 'quill/dist/quill.js',
                'Quill': 'quill/dist/quill.js'
        })
    ]
}

富文本组件

<template>

  <!--富文本编辑器-->

  <div class="app-container">

    <div class="avatar">

      <!-- 图片上传组件辅助-->

      <a-upload

        class="quill-upload"

        :action="url"

        name="file"

        :beforeUpload="beforeUpload"

        @change="uploadAttachment"

      >

        <a-button id="upBtn"> <a-icon type="upload" /> Upload </a-button>

      </a-upload>

    </div>

    <a-row>

      <div class="edit_container">

        <quill-editor

          class="editor"

          v-model="newContent"

          ref="myQuillEditor"

          :options="editorOption"

          @ready="onEditorReady($event)"

        >

        </quill-editor>

      </div>

    </a-row>

  </div>

</template>

<script>

// 这里是自定义的上传服务器地址,换成自己的

import { imgUrl } from "@/main";

let token = sessionStorage.getItem("token");

let base = imgUrl; // 域名

let url = base + "/file/upload?token=" + token; // 上传图片接口,

// toolbar工具栏的工具选项(默认展示全部)

const toolOptions = [

  ["bold", "italic", "underline", "strike"],

  ["blockquote", "code-block"],

  [{ header: 1 }, { header: 2 }],

  [{ list: "ordered" }, { list: "bullet" }],

  [{ script: "sub" }, { script: "super" }],

  [{ indent: "-1" }, { indent: "+1" }],

  [{ direction: "rtl" }],

  [{ header: [1, 2, 3, 4, 5, 6, false] }],

  [{ color: [] }, { background: [] }],

  [{ font: [] }],

  [{ align: [] }],

  ["clean"],

  ["link", "image"]

];

import Quill from "quill";

import { useUpImg } from "@/pages/api/personalCenter/index";  // 上传图片接口,用于复制图片用的,替换成自己上传图片的接口

import { quillEditor } from "vue-quill-editor";

import ImageResize from "quill-image-resize-module";

import "quill/dist/quill.core.css";

import "quill/dist/quill.snow.css";

import "quill/dist/quill.bubble.css";

Quill.register("modules/imageResize", ImageResize);

export default {

  name: "QuillEditorForm",

  components: {

    quillEditor

  },

  props: ["content"],

  data() {

    let that = this;

    return {

      uploadList: [],

      url,

      newContent: this.content, // 富文本内容

      // 富文本编辑器配置

      editorOption: {

        placeholder: "",

        theme: "snow", // or 'bubble'

        modules: {

          clipboard: {

            // 粘贴版,处理粘贴时候的自带样式

            matchers: [[Node.ELEMENT_NODE, this.HandleCustomMatcher]]

          },

          toolbar: {

            container: toolOptions, // 工具栏

            handlers: {

              image: function(value) {

                if (value) {

                  // 绑定上传图片按钮

                  console.log(document.querySelector("#upBtn"));

                  document.querySelector("#upBtn").click();

                } else {

                  this.quill.format("image", false);

                }

              }

            }

          },

          imageResize: {

            displayStyles: {

              backgroundColor: "black",

              border: "none",

              color: "white"

            },

            modules: ["Resize", "DisplaySize", "Toolbar"]

          }

        }

      }

    };

  },

  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;

            }

            this.uploadToServer(file, res => {

              // 获取光标内容

              var range = quill.getSelection();

              if (range) {

                this.zhanImg(res);

                //  将光标移动到图片后面

                this.$refs.myQuillEditor.quill.setSelection(range.index + 1);

              }

            });

          });

        }

      },

      false

    );

  },

  methods: {

    uploadToServer(file, callback) {

      var formData = new FormData();

后端要的,file图片数据必须传

      formData.append("file", file);

      formData.append("name", "file");

 //调上传接口 换成自己的 不过返回的数据要传入到callback中 

      useUpImg(this.url, formData).then(({ data: res }) => {

        callback(res);

      });

    },

    async beforeUpload(file) {

      const isJpgOrPng =

        file.type === "image/jpeg" ||

        file.type === "image/png" ||

        file.type === "image/img" ||

        file.type === "image/jpg";

      if (!isJpgOrPng) {

        this.$message.error("You can only upload JPG file!");

      }

      const isLt2M = file.size / 1024 / 1024 < 2;

      if (!isLt2M) {

        this.$message.error("Image must smaller than 2MB!");

      }

      // await this.isSize(file, 345, 150);

      return isJpgOrPng && isLt2M;

    },

    HandleCustomMatcher(node, Delta) {

      // 文字、图片等,从别处复制而来,清除自带样式,转为纯文本

      let ops = [];

      Delta.ops.forEach(op => {

        if (op.insert && typeof op.insert === "string") {

          ops.push({

            insert: op.insert

          });

        }

      });

      Delta.ops = ops;

      return Delta;

    },

    // 粘贴图片回显

    zhanImg(response) {

      if (response.success) {

        let quill = this.$refs.myQuillEditor.quill;

        // 获取光标所在位置

        let length = quill.getSelection().index;

        // 插入图片  需要替换为自己服务器返回的图片地址

        let imgPath = base + "/images/" + response.data + "?token=" + token;

        quill.insertEmbed(length, "image", imgPath);

        quill.setSelection(length + 1);

      }

    },

    uploadAttachment(response, file, fileList) {

      // 保存文件信息

      // 获取富文本组件实例

      if (response.file.status === "done") {

        console.log(response);

        let quill = this.$refs.myQuillEditor.quill;

        // 获取光标所在位置

        let length = quill.getSelection().index;

        // 插入图片  需要替换为自己服务器返回的图片地址

        let imgPath =

          base + "/images/" + response.file.response.data + "?token=" + token;

        quill.insertEmbed(length, "image", imgPath);

        quill.setSelection(length + 1);

        // 清空文件列表

      }

    },

    onEditorReady(editor) {

      // console.log(this.content);

      document.querySelector("div.ql-editor").innerHTML = this.newContent;

    }, // 准备编辑器

    sendMsg(newval) {

      this.$emit("msgEvent", this.newContent);

    }

  },

  watch: {

    newContent(val, newval) {

      this.sendMsg(newval);

    }

  }

};

</script>

<style lang="less" scoped>

.quill-editor {

  line-height: normal !important;

  height: 500px !important;

}

.avatar {

  display: none;

}

/deep/ .ql-disabled {

  background-color: #f5f7fa;

  border-color: #e4e7ed;

  color: #c0c4cc;

  cursor: not-allowed;

}

/*.edit_container {*/

/*  position: relative;*/

/*}*/

</style>

 父组件使用

引入

import myDomEditor from "./myDomEditor.vue"; // 富文本组件

注册

  components: {
    myDomEditor
  },

使用

     <myDomEditor
              :content="content"  // v-mode绑定值
              @msgEvent="msgEvent($event)"
            ></myDomEditor>

data :

  data() {
content:''
}

methods:

  methods: {
    msgEvent(e) {
      // console.log(e);
      this.content = e;
    },
}

如果需要回显赋值就直接
this.content = res.data.content  // 类似 ,直接就传到子组件中了

 前台页面渲染

    <div class="ql-editor" v-html="XXXX"></div>

 效果

 

 

 

 

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 14
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

湖光一天雷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值