使用vue-quill-editor编辑器--自定义上传图片-图片拖拽-鼠标悬停提示

quill的官网

在vue里面使用quill的扩展模块vue-quill-editor
效果图:
实现:
1.鼠标悬停时的提示,
2.因为编辑器默认图片是base64格式,所以需要自定义上传图片到服务器,通过服务器给的ID返回给后端,后端再给出URL然后前端插入在编辑器中
3.图片的拖拽和缩放
在这里插入图片描述

1、下载Vue-Quill-Editor

npm install vue-quill-editor --save

2、下载quill(Vue-Quill-Editor需要依赖)

npm install quill --save

3、拖拽,缩放模块

npm install quill-image-resize-module quill-image-drop-module --save

两种引用方法:全局引用和局部引用

  • 全局引用

项目入口文件中(main.js)注册(也可以写在一个js里面然后把这个js引到main里面)
在这里插入图片描述

import Vue from 'vue'
import VueQuillEditor from 'vue-quill-editor'

// require styles
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'

Vue.use(VueQuillEditor)

局部引用,在需调用的vue页面中声明

import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'

import {
    
     quillEditor } from 'vue-quill-editor'

export default {
    
    
  components: {
    
    
    quillEditor
  }
}

局部代码:

<template>
    <div>
      <quill-editor 
    ref="myQuillEditor"
    @change='onEditorChange' 
    :content="content"
    :options="editorOption"></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';

export default {
    
    
    data(){
    
    
        return{
    
    
            content: '',
            editorOption: {
    
    
               placeholder: '编辑文章内容'
             },
        }
    },
    components: {
    
    
        quillEditor
    },
    methods:{
    
    
        onEditorChange({
    
     editor, html, text }) {
    
    
            this.content = html;
        },
    }
}
</script>

我是全局引入的
全部代码:

<template>
<div class="box">
    <el-upload
        class="avatar-uploader"
        action="#"
        name="img"
        :show-file-list="false"
        :auto-upload="false"
        :on-change="changeFile"
        :before-upload="beforeUpload">
        </el-upload>
  <!-- 富文本编辑器组件 -->
  <el-row v-loading="uillUpdateImg">
  <quill-editor 
    ref="myQuillEditor"
    @change='onEditorChange' 
    :content="content"
    :options="editorOption"></quill-editor>
    <!-- 显示字数 -->
    <span class="sizeTishi">{
    
    {
    
    tiLength}}/10000</span>
  </el-row>
</div>
</template>

<script>
import editorTarbar from '@/utils/editorTarbar' //头部的功能配置
import uploadPicToIOBS from '@/api/content/article/api.js'
import {
    
     saveImageUploadRecord, getIobsUrl } from '@/api/content/article'
export default {
    
    
    props:{
    
    
    //我的内容
        ArticleContent:{
    
    
            type: String,
            default: ''
        }
    },
    data () {
    
    
        return {
    
    
            uillUpdateImg:false, //显示loading动画
            content:this.ArticleContent,
            tiLength: 0,//默认显示字数
            toolbarTips: editorTarbar.toolbarTips,//头部功能的鼠标悬停提示
            editorOption:{
    
    
                modules:{
    
    
                //图片的缩放和拖拽
                    imageResize: {
    
    
                        displayStyles: {
    
    
                        backgroundColor: 'black',
                        border: 'none',
                        color: 'white'
                        },
                        modules: ['Resize', 'DisplaySize', 'Toolbar']
                    },
                    toolbar:{
    
     // 工具栏
                        container: editorTarbar.toolbar,
                        handlers: {
    
    
                            'image': function (value) {
    
    
                                if (value) {
    
    
                                    // upload点击上传事件  value打出来是true,avatar-uploader 就是上面编辑器绑定的class
                                    document.querySelector('.avatar-uploader input').click()
                                } else {
    
    
                                this.quill.format('image', false)
                                }
                            }
                        }
                    }
                }
            },
            imageFileList:[],
            fileList:[],// 选中的标签

        } 
    },
    //一定要有这个,前面么有写这个导致我的字数和内容一直不出来
    computed: {
    
    
      editor() {
    
    
        return this.$refs.myQuillEditor.quill
      }
    },
    mounted () {
    
    
            console.log('this is current quill instance object', this.editor)
            autotip:{
    
    
                document.getElementsByClassName('ql-editor')[0].dataset.placeholder=''
                for(let item of this.toolbarTips){
    
    
                    let tip = document.querySelector('.quill-editor '+ item.Choice) 
                    if (!tip) continue 
                    tip.setAttribute('title',item.title)}
            }
            console.log(1111, this.content, this.$refs.myQuillEditor)
            this.tiLength = this.$refs.myQuillEditor.quill.getLength()-1
    },
    //实现双向绑定
    watch: {
    
    
      ArticleContent: function (newVal) {
    
    
          console.log(123123, newVal);
        this.tiLength = this.$refs.myQuillEditor.quill.getLength()-1
        this.content = newVal
      }
    },
    methods:{
    
    
        //内容改变事件
        onEditorChange (e){
    
    
            if(e){
    
    
                console.log('我被触发改变了',e);
                this.content = e.html
                this.$emit('change',e.html)
                e.quill.deleteText(10000,4)
                this.tiLength=this.content===''? 0 : this.tiLength=e.quill.getLength()-1
            }
        },
        // onEditorBlur(){//失去焦点事件
        //     },
        // onEditorFocus(){//获得焦点事件
        // },
        beforeUpload(){
    
    },
           // blob转base64
        blobToDataURL(input) {
    
    
            //  我是上传到专门放图片的服务器,自定义上传图片,原本图片默认是base64 格式的,但是使用el-upload组件上传就不需要转,这里的转格式代码被我删掉了
            //  上传图片
            uploadPicToIOBS(input).then(res => {
    
    
                console.log(res, '图片')
                // 成功之后拿到返回值,返给后端拿到url
                let data={
    
    
                imageFileId:res[0].imageFileId,
                bucket:res[0].bucket,
                }
                console.log(data);
                //发送拿URL的借口请求
                getIobsUrl(data).then(res=>{
    
    
                    console.log(res,'我是链接');
                    if(res.code=='000000'){
    
    
                    //拿到url插入到编辑器中
                        let quill = this.$refs.myQuillEditor.quill;
                        //找光标所在位置
                        let length = quill.getSelection().index
                        // 插入图片  dt.url为服务器返回的图片地址
                        quill.insertEmbed(length, 'image', res.data.imageUrl)
                        // 调整光标到最后
                        quill.setSelection(length + 1)
                    }
                })
            }).catch(err => {
    
    
                console.log(err, 'errsdscs')
            })
        },
          // 这里注意:自定义上传不会出发成功的回调,所以调用接口写在这里
          //上传发生变化时
        changeFile(file, fileList) {
    
    
            console.log(file, fileList, 'changeFile')
            this.fileList = fileList.map(item => item)
            console.log(this.fileList, 'filterList')
            // 如果不修改图片就直接拿之前的图片参数,如果修改就是拿得到的参数
            // 转base64
            this.blobToDataURL(file.raw)
            console.log(this.fileList, '00000')
            }
        }
}
</script>

<style scoped>
/deep/ .ql-snow .ql-picker {
    
    
height: 30px;
}

/deep/ .ql-snow .ql-picker.ql-size {
    
    
    width: 80px;
}
/deep/ .ql-snow .ql-picker.ql-header {
    
    
    width: 80px;
}
/deep/ .ql-snow .ql-picker.ql-font {
    
    
    width: 100px;
}
/* .avatar-uploader{
	display: none;
} */
</style>

editorTarbar文件

let toolbar=
  [
    ['bold', 'italic', 'underline', 'strike'],   // 加粗,斜体,下划线,删除线buttons
     ['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'],//链接,图片
  ]
let toolbarTips=[ 
  {
    
    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-block',title:'插入代码段'}, 
  {
    
    Choice:'.ql-size',title:'字体大小'}, 
  {
    
    Choice:'.ql-list[value="ordered"]',title:'编号列表'}, 
  {
    
    Choice:'.ql-list[value="bullet"]',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-video',title:'视频'}, 
  {
    
    Choice:'.ql-link',title:'添加链接'}, 
  {
    
    Choice:'.ql-formula',title:'插入公式'}, 
  {
    
    Choice:'.ql-clean',title:'清除格式'}, 
  {
    
    Choice:'.ql-indent[value="-1"]',title:'向左缩进'}, 
  {
    
    Choice:'.ql-indent[value="+1"]',title:'向右缩进'}, 
  {
    
    Choice:'.ql-direction',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 {
    
    
  toolbar,toolbarTips
}

出现的问题:
1:在这里插入图片描述

:auto-upload="false"

这个没写导致我在点击上传图片按钮的时候传了2次。

2:在这里插入图片描述
现实字数,通过后端返回的数据渲染在编辑中,字数不会检测出字数多少,依旧为0
在这里插入图片描述
写了watch和computed就解决了

3.拿到url后引入到鼠标光标所在位置
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_48371382/article/details/115357446
今日推荐