vue-quill-editer进阶(代码完整版)

此篇笔记记录的是vue-quill-edter的进阶版,如果还没有安装过quill需要查看 https://www.cnblogs.com/meiyanstar/p/12909755.html(vue-quill-editer安装初级版)

实现功能步骤:

  1. 设置工具栏展示的工具选项
  2.  工具栏功能提示
  3. 事件重写,实现文件上传功能
  4. 事件重写,实现图片上传功能
    • 实现图片拖拽上传
    • 实现上传到富文本里的图片进行拖拽改变图片大小
  5. 父组件调用

一、富文本组件页面全部代码(QuillEditer.vue)

/**变量说明:
 content:文本框中的内容。
 quillConfig:全部相关配置
 **/
 <template>
   <div class="edit_container">
     <quill-editor
       class="ql-editor"
       v-model="content"
        :id="id"
        :ref="refs"
        :options="quillOption"
        @focus="onEditorFocus($event)"
        @blur="onEditorBlur($event)"
        @change="onEditorChange($event)"
      ></quill-editor>
    </div>
  </template>
  
  <script>
  import 'quill/dist/quill.core.css'
  import 'quill/dist/quill.snow.css'
  import 'quill/dist/quill.bubble.css'
  import { quillEditor } from 'vue-quill-editor'
  import quillConfig from '@/utils/quillconfig.js'
  import 'quill/dist/quill.min.js'
  
  // 上传文件 插入a链接
  import { Quill } from 'vue-quill-editor'
  // 自定义插入a链接
  var Link = Quill.import('formats/link')
  class FileBlot extends Link {
    // 继承Link Blot
    static create(value) {
      let node = undefined
      if (value && !value.href) {
        // 适应原本的Link Blot
        node = super.create(value)
      } else {
        // 自定义Link Blot
        node = super.create(value.href)
        // node.setAttribute('download', value.innerText);  // 左键点击即下载
        node.innerText = value.innerText
        node.download = value.innerText
      }
      return node
    }
  }
  FileBlot.blotName = 'link'
  FileBlot.tagName = 'A'
  Quill.register(FileBlot)
  // 上传文件 插入a链接over
  
  export default {
    name: 'VueQuillEditor',
    components: {
      quillEditor
    },
    props: ['id', 'refs', 'quillContent'],
    data () {
      return {
        content: null, // 富文本内容
        quillOption: quillConfig,//各配置项
      }
    },
    created () {
      this.content = this.quillContent
    },
    mounted() {
       autotip:{
            document.getElementsByClassName('ql-editor')[0].dataset.placeholder=''
            for(let item of quillConfig.titleConfig){
                let tip = document.querySelector('.quill-editor '+ item.Choice)
                if (!tip) continue
                tip.setAttribute('title',item.title)
            }
        }
    },
    methods: {
      // 失去焦点事件
      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.content = html
        this.$emit('childQuill',html)
      },
    }
  }
  </script>
 
 <style scoped >
 .ql-editor {
   line-height: normal !important;
   /* width: 335px;  我是需要展示给手机端所以设置了宽 */
 }
 .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>
 <style>
 /* 自定义上传文件的icon */
 .ql-upload{
       background-image: url("../assets/images/file.svg") !important;
       background-size: 16px 16px !important;
       background-position: center center !important;
       background-repeat:no-repeat !important;
 }
 /* 隐藏文件上传的input type=file的样式 */
 input.ql-upload {
   height: 0 !important;
   width: 0 !important;
   padding: 0 !important;
 }
 </style>

 

二、富文本配置的全部代码(quillconfig.js)

 

 import { 
     quillUploadimgAndfile
   } 
   from "@/api/wenjuan";   //上传图片和文件的接口
 //quill图片可拖拽上传
 import { ImageDrop } from 'quill-image-drop-module';
 Quill.register('modules/imageDrop', ImageDrop);
 //quill图片可拖拽改变大小
 import ImageResize from 'quill-image-resize-module'
  Quill.register('modules/imageResize', ImageResize)
     
  // 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'}],
      [{'size': ['small', false, 'large', 'huge']}],
      [{'header': [1, 2, 3, 4, 5, 6, false]}],
      [{'color': []}, {'background': []}],
      [{'font': []}],
      [{'align': []}],
      ['clean'],
      ['link', 'image'],
      ['upload'],
  ];
    
  const handlers = {
    //   实现图片上传功能
      image: function image() {
          var self = this;
          var fileInput = this.container.querySelector('input.ql-image[type=file]');
          if (fileInput === null) {
              fileInput = document.createElement('input');
              fileInput.setAttribute('type', 'file');
              // 设置图片参数名
              fileInput.setAttribute('name', 'file');
              // 可设置上传图片的格式
              fileInput.setAttribute('accept','image/png, image/gif, image/jpeg, image/bmp, image/x-icon');
              fileInput.classList.add('ql-image');
              // 监听选择文件
              fileInput.addEventListener('change', function () {
                let formData = new FormData()
                formData.append('file',fileInput.files[0])
                quillUploadimgAndfile(formData).then(data => {//quillUploadimgAndfile是封装好的上传文件的方法
                    if (data.data.code === 1) {
                        let length = self.quill.getSelection(true).index;
                        self.quill.insertEmbed(length, 'image', data.data.data.url);
                        self.quill.insertEmbed(length, 'title', data.data.data.fileName);
                        self.quill.setSelection(length + 1)
                    }else {
                        this.$message.error(data.data.info)
                    }
                }).catch(err => {
                    
                })
              });
              this.container.appendChild(fileInput);
          }
          fileInput.click();
      },
    //   实现文件上传功能
      upload:function upload() {
            var self = this;
            var fileInput = self.container.querySelector('input.ql-upload[type=file]');
            if (fileInput === null) {
                fileInput = document.createElement('input');
                fileInput.setAttribute('type', 'file');
                // 设置图片参数名
                fileInput.setAttribute('name', 'file');
                // 限制上传文件的格式  具体限制格式类型见文章底部
              //   fileInput.setAttribute('accept','image/png, image/gif, image/jpeg, image/bmp, image/x-icon');
                fileInput.classList.add('ql-upload');
                // 监听选择文件
                console.log('self.quill',self.quill)
                fileInput.addEventListener('change', function () {
                  let formData = new FormData()
                  formData.append('file',fileInput.files[0])
                  quillUploadimgAndfile(formData).then(data => {//quillUploadimgAndfile是封装好的上传文件的方法
                      if (data.data.code === 1) {
                          console.log('asdasda',data.data.data)
                          let length = self.quill.getSelection(true).index;
                          // 插入文件,data为服务器返回的文件链接地址
                          //**注意这里 - 插入文件地址的方式**
                          self.quill.insertEmbed(length, 'link', {href: data.data.data.url, innerText: data.data.data.leName}) 
                          self.quill.setSelection(length + 1)
                      }else {
                          self.$message.error(data.data.info)
                      }
                  }).catch(err => {
                      
                  })
                });
                this.container.appendChild(fileInput);
            }
            fileInput.click();
     }
 };
 // 工具栏功能提示
 const titleConfig=[
     {Choice:'.ql-bold',title:'加粗'},
     {Choice:'.ql-italic',title:'斜体'},
     {Choice:'.ql-underline',title:'下划线'},
     {Choice:'.ql-header',title:'段落格式'},
     {Choice:'.ql-strike',title:'删除线'},
     {Choice:'.ql-blockquote',title:'块引用'},
     {Choice:'.ql-code',title:'插入代码'},
     {Choice:'.ql-code-block',title:'插入代码段'},
     {Choice:'.ql-font',title:'字体'},
     {Choice:'.ql-size',title:'字体大小'},
     {Choice:'.ql-list[value="ordered"]',title:'编号列表'},
     {Choice:'.ql-list[value="bullet"]',title:'项目列表'},
     {Choice:'.ql-direction',title:'文本方向'},
     {Choice:'.ql-header[value="1"]',title:'h1'},
     {Choice:'.ql-header[value="2"]',title:'h2'},
     {Choice:'.ql-align',title:'对齐方式'},
     {Choice:'.ql-color',title:'字体颜色'},
     {Choice:'.ql-background',title:'背景颜色'},
     {Choice:'.ql-image',title:'图像'},
     {Choice:'.ql-upload',title:'文件'},
     {Choice:'.ql-link',title:'添加链接'},
     {Choice:'.ql-formula',title:'插入公式'},
     {Choice:'.ql-clean',title:'清除字体格式'},
     {Choice:'.ql-script[value="sub"]',title:'下标'},
     {Choice:'.ql-script[value="super"]',title:'上标'},
     {Choice:'.ql-indent[value="-1"]',title:'向左缩进'},
     {Choice:'.ql-indent[value="+1"]',title:'向右缩进'},
     {Choice:'.ql-header .ql-picker-label',title:'标题大小'},
     {Choice:'.ql-header .ql-picker-item[data-value="1"]',title:'标题一'},
     {Choice:'.ql-header .ql-picker-item[data-value="2"]',title:'标题二'},
     {Choice:'.ql-header .ql-picker-item[data-value="3"]',title:'标题三'},
     {Choice:'.ql-header .ql-picker-item[data-value="4"]',title:'标题四'},
     {Choice:'.ql-header .ql-picker-item[data-value="5"]',title:'标题五'},
     {Choice:'.ql-header .ql-picker-item[data-value="6"]',title:'标题六'},
     {Choice:'.ql-header .ql-picker-item:last-child',title:'标准'},
     {Choice:'.ql-size .ql-picker-item[data-value="small"]',title:'小号'},
     {Choice:'.ql-size .ql-picker-item[data-value="large"]',title:'大号'},
     {Choice:'.ql-size .ql-picker-item[data-value="huge"]',title:'超大号'},
     {Choice:'.ql-size .ql-picker-item:nth-child(2)',title:'标准'},
     {Choice:'.ql-align .ql-picker-item:first-child',title:'居左对齐'},
     {Choice:'.ql-align .ql-picker-item[data-value="center"]',title:'居中对齐'},
     {Choice:'.ql-align .ql-picker-item[data-value="right"]',title:'居右对齐'},
     {Choice:'.ql-align .ql-picker-item[data-value="justify"]',title:'两端对齐'}
 ];
 export default {
     placeholder: '',
     theme: 'snow',  // 主题
     modules: {
         toolbar: {
             container: toolOptions,  // 工具栏选项
             handlers: handlers,  // 事件重写
            
         },
         imageResize: {},// 拖拽改变图片大小
         imageDrop:true, // 拖拽上传文件
     },
     titleConfig,
161 };

 

补充:上传文件限制类型:https://www.cnblogs.com/meiyanstar/p/14676408.html

三、父组件页面调用富文本

<template>
  <div>
    <div class="container">
      <QuillEditor ref="quillEditor" :quillContent="ruleForm.ext" @onEditorBlur="onEditorBlur" class="quillbox ql-editor"></QuillEditor>
      <el-button type="primary" @click="submit" :loading="loading">保存</el-button>
    </div>
  </div>
</template>

<script>
import QuillEditor from '@/components/QuillEditor.vue'; // 富文本组件

export default {
  components: {
    QuillEditor, // 富文本组件
  },
  data() {
    return {
      ruleForm: {
        ext: '', //富文本的内容
      },
      loading: false,
    };
  },
  inject: ['reload'],
  mounted() {
    this.getPopdata();//获取默认数据
  },
  methods: {
    getPopdata() {},
    submit() {
      this.loading = true;
      this.$refs['ruleFormRef'].validate((valid) => {
        if (valid) {
              this.loading = false;//保存成功后loading置为false
        }
      });
    },
    // 富文本失去焦点事件
    onEditorBlur(val) {
      this.ruleForm.ext = val;
    },
  },
};
</script>
<style lang="scss" scoped>
</style>

 

posted @ 2021-04-07 10:22  小那  阅读(1448)  评论(2编辑  收藏  举报