zoukankan      html  css  js  c++  java
  • 7.Vue-Quill-Editor图片插入自定义

    Vue-Quill-Editor图片插入自定义

    前言:

    因为在项目中前端采用了Vue来实现,正好用到了富文本编辑器这一块,于是,经过技术上的选择,决定使用Vue-Quill-Editor。

    使用的过程相对简单,但是图片插入时,保留的是base64二进制形式,会导致数据库字段太长,存储不易。

    所以再三斟酌,决定使用Element-UI的Upload插件来进行图片的上传。

    代码:

    <template>
        <div class="bg">
            <!-- 图片上传组件辅助-->
          <el-upload
            class="avatar-uploader"
            :action="serverUrl"
            :headers="header"
            :show-file-list="false"
            :on-success="uploadSuccess"
            :on-error="uploadError"
            :before-upload="beforeUpload">
          </el-upload>
    
            <quill-editor 
            class="editor"
            v-model="content"
            ref="myQuillEditor" 
            :options="editorOption" 
            @blur="onEditorBlur($event)" @focus="onEditorFocus($event)"
            @change="onEditorChange($event)">
            </quill-editor>
        </div>
    </template>
    <script>
    // 工具栏配置
    const toolbarOptions = [
      ["bold", "italic", "underline", "strike"], // 加粗 斜体 下划线 删除线
      ["blockquote", "code-block"], // 引用  代码块
      [{ header: 1 }, { header: 2 }], // 1、2 级标题
      [{ 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"] // 链接、图片、视频
    ];
    
    import {quillEditor,Quill} from "vue-quill-editor";
    import "quill/dist/quill.core.css";
    import "quill/dist/quill.snow.css";
    import "quill/dist/quill.bubble.css";
    import {ImageResize} from 'quill-image-resize-module';
    Quill.register('modules/imageResize', ImageResize)
    
    export default {
      props: {
        /*编辑器的内容*/
        value: {
          type: String
        },
        /*图片大小*/
        maxSize: {
          type: Number,
          default: 4000 //kb
        },
    
        imagesValue:{
          type:String,
          default:null
        }
      },
    
      components: {
        quillEditor,
        Quill,
        ImageResize,
      },
    
      data() {
        return {
          content: this.value,
          quillUpdateImg: false, // 根据图片上传状态来确定是否显示loading动画,刚开始是false,不显示
          editorOption: {
            //placeholder: "",
            theme: "snow", // or 'bubble'
            placeholder: "您想说点什么?",
            modules: {
              toolbar: {
                container: toolbarOptions,
                // container: "#toolbar",
                handlers: {
                  image: function(value) {
                    if (value) {
                      // 触发input框选择图片文件
                      document.querySelector(".avatar-uploader input").click();
                    } else {
                      this.quill.format("image", false);
                    }
                  },
                  // link: function(value) {
                  //   if (value) {
                  //     var href = prompt('请输入url');
                  //     this.quill.format("link", href);
                  //   } else {
                  //     this.quill.format("link", false);
                  //   }
                  // },
                }
              },
              imageResize:{
              }
            },
    
          },
          serverUrl: "/api/upload/news", // 这里写你要上传的图片服务器地址
          imageUrl:'',
          images:null,
          header: {
            token: sessionStorage.token
          } // 有的图片服务器要求请求头需要有token
        };
      },
    
      methods: {
        onEditorBlur() {
          //失去焦点事件
        },
        onEditorFocus() {
          //获得焦点事件
        },
        onEditorChange() {
          //内容改变事件
          this.$emit("input", this.content,this.images);
        },
    
        // 富文本图片上传前
        beforeUpload(file) {
          console.log("1."+file)
          this.quillUpdateImg = true;
        },
    
        uploadSuccess(res, file) {
          console.log("2."+file)
          this.imageUrl = file.response
          this.images = (this.images==null?"":(this.images+"#")) + this.imageUrl
          // res为图片服务器返回的数据
          // 获取富文本组件实例
          let quill = this.$refs.myQuillEditor.quill;
    
          let length = quill.getSelection().index;
            // 插入图片  res.url为服务器返回的图片地址
          quill.insertEmbed(length, "image", this.imageUrl);
            // 调整光标到最后
          quill.setSelection(length + 1);
          // loading动画消失
          this.quillUpdateImg = false;
        },
        // 富文本图片上传失败
        uploadError() {
          // loading动画消失
          this.quillUpdateImg = false;
          this.$message.error("图片上传失败");
        }
      },
      created() {
          this.content=this.value
          this.images=this.imagesValue
      }
    };
    </script> 
    
    <style>
    
    .bg {
       100%;
      margin: 0 auto;
    }
    
    .editor {
      line-height: normal !important;
      height: 750px;
    }
    .ql-snow .ql-tooltip[data-mode=link]::before {
      content: "请输入链接地址:";
    }
    .ql-snow .ql-tooltip.ql-editing a.ql-action::after {
        border-right: 0px;
        content: '保存';
        padding-right: 0px;
    }
    
    .ql-snow .ql-tooltip[data-mode=video]::before {
        content: "请输入视频地址:";
    }
    
    .ql-snow .ql-picker.ql-size .ql-picker-label::before,
    .ql-snow .ql-picker.ql-size .ql-picker-item::before {
      content: '14px';
    }
    .ql-snow .ql-picker.ql-size .ql-picker-label[data-value=small]::before,
    .ql-snow .ql-picker.ql-size .ql-picker-item[data-value=small]::before {
      content: '10px';
    }
    .ql-snow .ql-picker.ql-size .ql-picker-label[data-value=large]::before,
    .ql-snow .ql-picker.ql-size .ql-picker-item[data-value=large]::before {
      content: '18px';
    }
    .ql-snow .ql-picker.ql-size .ql-picker-label[data-value=huge]::before,
    .ql-snow .ql-picker.ql-size .ql-picker-item[data-value=huge]::before {
      content: '32px';
    }
    
    .ql-snow .ql-picker.ql-header .ql-picker-label::before,
    .ql-snow .ql-picker.ql-header .ql-picker-item::before {
      content: '文本';
    }
    .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before,
    .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before {
      content: '标题1';
    }
    .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before,
    .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before {
      content: '标题2';
    }
    .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before,
    .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before {
      content: '标题3';
    }
    .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before,
    .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before {
      content: '标题4';
    }
    .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before,
    .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before {
      content: '标题5';
    }
    .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before,
    .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before {
      content: '标题6';
    }
    
    .ql-snow .ql-picker.ql-font .ql-picker-label::before,
    .ql-snow .ql-picker.ql-font .ql-picker-item::before {
      content: '标准字体';
    }
    .ql-snow .ql-picker.ql-font .ql-picker-label[data-value=serif]::before,
    .ql-snow .ql-picker.ql-font .ql-picker-item[data-value=serif]::before {
      content: '衬线字体';
    }
    .ql-snow .ql-picker.ql-font .ql-picker-label[data-value=monospace]::before,
    .ql-snow .ql-picker.ql-font .ql-picker-item[data-value=monospace]::before {
      content: '等宽字体';
    }
    </style>
    

    组件的使用方法:

    <Editor v-if="step==2" @input="chTwo"  :value="news.context" :imagesValue="news.images"/>
    

    上传图片到服务器后回返图片路径,

    核心代码:

        uploadSuccess(res, file) {
          console.log("2."+file)
          this.imageUrl = file.response
          this.images = (this.images==null?"":(this.images+"#")) + this.imageUrl
          // res为图片服务器返回的数据
          // 获取富文本组件实例
          let quill = this.$refs.myQuillEditor.quill;
    
          let length = quill.getSelection().index;
            // 插入图片  res.url为服务器返回的图片地址
          quill.insertEmbed(length, "image", this.imageUrl);
            // 调整光标到最后
          quill.setSelection(length + 1);
          // loading动画消失
          this.quillUpdateImg = false;
        },
    
  • 相关阅读:
    HTML DOM 12 表格排序
    HTML DOM 10 常用场景
    HTML DOM 10 插入节点
    HTML DOM 09 替换节点
    HTML DOM 08 删除节点
    HTML DOM 07 创建节点
    022 注释
    024 数字类型
    005 基于面向对象设计一个简单的游戏
    021 花式赋值
  • 原文地址:https://www.cnblogs.com/TimerHotel/p/vue_07.html
Copyright © 2011-2022 走看看