vue3中QuillEditor封装使用

<template>

    <el-upload

        :action="uploadUrl"

        :headers="uploadToken"

        :before-upload="handleBeforeUpload"

        :on-success="handleUploadSuccess"

        :on-error="handleUploadError"

        name="file"

        :show-file-list="false"

        class="editor-img-uploader"

        v-if="props.type === 'url'"

    >

        <i ref="uploadRef" class="Plus editor-img-uploader"></i>

    </el-upload>

    <div class="editor">

        <QuillEditor id="editorId" ref="myQuillEditor" v-model:content="editorContent" contentType="html" :options="options" />

        <!--文本改变时触发-->

        <!--    @update:content="onContentChange($event)"-->

    </div>

</template>

<script setup lang="ts">

import { QuillEditor, Quill } from '@vueup/vue-quill';

import '@vueup/vue-quill/dist/vue-quill.snow.css';

import { getCurrentInstance, reactive, ref, toRaw, computed } from 'vue';

import { Session } from '/@/utils/storage';

import envConfig from '/@/utils/envConfig';

// import imageResize from 'quill-image-resize-module';

// Quill.register('modules/imageResize', imageResize);

// import { ImageDrop } from 'quill-image-drop-module';

// Quill.register('modules/imageDrop', ImageDrop);

const { proxy } = getCurrentInstance();

const emit = defineEmits(['update:content', 'getFileId']);

const props = defineProps({

    /* 编辑器的内容 */

    content: {

        type: String,

        default: '',

    },

    /* 只读 */

    readOnly: {

        type: Boolean,

        default: false,

    },

    // 上传文件大小限制(MB)

    fileSize: {

        type: Number,

        default: 5,

    },

    /* 类型(base64格式、url格式) */

    type: {

        type: String,

        default: 'url',

    },

});

const editorContent = computed({

    get: () => props.content,

    set: (val) => {

        emit('update:content', val);

    },

});

const myQuillEditor = ref(null);

const uploadUrl = ref(envConfig.service.STORAGE + 'system/minio/uploadFile'); // 上传的图片服务器地址

const uploadToken = ref({ token: Session.get('token'), orgCode: envConfig.app.orgCode, uuId: Session.get('uuid') }); // token

// const uploadData = ref({ orgId: Session.get('userInfo').orgId }); // 上传时附带的额外参数

const options = reactive({

    theme: 'snow',

    debug: 'warn',

    modules: {

        // 工具栏配置

        toolbar: {

            container: [

                ['bold', 'italic', 'underline', 'strike'], // 加粗 斜体 下划线 删除线

                ['blockquote', 'code-block'], // 引用  代码块

                [{ list: 'ordered' }, { list: 'bullet' }], // 有序、无序列表

                [{ indent: '-1' }, { indent: '+1' }], // 缩进

                [{ size: ['small', false, 'large', 'huge'] }], // 字体大小

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

                [{ color: [] }, { background: [] }], // 字体颜色、字体背景颜色

                [{ align: [] }], // 对齐方式

                ['clean'], // 清除文本格式

                ['link', 'image', 'video'], // 链接、图片、视频

            ],

            handlers: {

                // 重写图片上传事件

                image: function (value) {

                    if (value) {

                        //调用图片上传

                        proxy.$refs.uploadRef.click();

                    } else {

                        Quill.format('image', true);

                    }

                },

            },

        },

        // imageDrop: true, //图片拖拽

        // imageResize: {

        //  //放大缩小

        //  displayStyles: {

        //      backgroundColor: 'black',

        //      border: 'none',

        //      color: 'white',

        //  },

        //  modules: ['Resize', 'DisplaySize', 'Toolbar'],

        // },

    },

    placeholder: '请输入内容',

    readOnly: props.readOnly,

});

// 上传前校检格式和大小

// function handleBeforeUpload(file) {

//  const type = ['image/jpeg', 'image/jpg', 'image/png', 'image/svg'];

//  const isJPG = type.includes(file.type);

//  //检验文件格式

//  if (!isJPG) {

//      // proxy.$modal.msgError(`图片格式错误!`);

//      return false;

//  }

//  // 校检文件大小

//  if (props.fileSize) {

//      const isLt = file.size / 1024 / 1024 < props.fileSize;

//      if (!isLt) {

//          // proxy.$modal.msgError(`上传文件大小不能超过 ${props.fileSize} MB!`);

//          return false;

//      }

//  }

//  return true;

// }

// 上传成功处理

function handleUploadSuccess(res, file) {

    // 如果上传成功

    if (res.code == 0) {

        console.log(res);

        // 获取富文本实例

        let quill = toRaw(myQuillEditor.value).getQuill();

        // 获取光标位置

        let length = quill.selection.savedRange.index;

        // 插入图片,res为服务器返回的图片链接地址

        let imageUrl = res.data[0].url;

        quill.insertEmbed(length, 'image', imageUrl);

        // 调整光标到最后

        quill.setSelection(length + 1);

        emit('getFileId', res.fileId);

    } else {

        // proxy.$modal.msgError('图片插入失败');

    }

}

// 上传失败处理

// function handleUploadError() {

//  proxy.$modal.msgError('图片插入失败');

// }

</script>

<style>

.editor,

.ql-toolbar {

    white-space: pre-wrap !important;

    line-height: normal !important;

}

.editor-img-uploader {

    display: none;

}

.ql-editor {

    min-height: 200px;

}

.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>

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值