浅谈vue中使用编辑器vue-quill-editor踩过的坑

作者:maggie_live 时间:2024-04-10 13:46:00 

结合vue+element-ui+vue-quill+editor二次封装成组件

1.图片上传

分析原因

项目中使用vue-quill-editor富文本编辑器,在编辑内容的时候,我们往往会编辑图片,而vue-quill-editor默认的处理方式是直接将图片转成base64格式,导致上传的内容十分庞大,且服务器接受post的数据的大小是有限制的,很有可能就提交失败,造成用户体验差。

引入element-ui

编辑editor.vue文件


<template>
 <div>
   <!-- 图片上传组件辅助-->
   <el-upload
     class="avatar-uploader"
     action=""
     accept="image/jpg, image/jpeg, image/png, image/gif"
     :http-request="upload"
     :before-upload="beforeUploadImg"
     :on-success="uploadSuccess"
     :on-error="uploadError"
     :show-file-list="false">
     <i class="el-icon-plus avatar-uploader-icon"></i>
   </el-upload>
 </div>
</template>
<script>
 import axios from '@/API/';
import { quillEditor } from "vue-quill-editor";
import COS from "cos-js-sdk-v5";
import Upload from '@/components/Upload.vue';
import { addQuillTitle } from '../utils/quill-title.js';

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

export default {
   data() {
     return {
     }
   },
   methods: {
     // 上传图片前
     beforeUpload(res, file) {
     const isJPG = file.type === 'image/jpg' || file.type === 'image/png' || file.type === 'image/jpeg'
   const isLt1M = file.size / 1024 / 1024 < 1
   if (!isJPG) {
     this.$message.error('支持JPG、PNG格式的图片,大小不得超过1M')
   }
   if (!isLt1M) {
     this.$message.error('文件最大不得超过1M')
   }
   return isJPG && isLt1M
     },
     // 上传图片成功
     uploadSuccess(res, file) {},
     // 上传图片失败
     uploadError(res, file) {},
     // 上传图片处理过程
     upload(req){}
   }
 }
</script>

在editor.vue中引入vue-quill-editor


<template>
 <div>
   <!-- 图片上传组件辅助-->
   <el-upload
     class="avatar-uploader"
     action=""
     accept="image/jpg, image/jpeg, image/png, image/gif"
     :http-request="upload"
     :before-upload="beforeUploadImg"
     :on-success="uploadSuccess"
     :on-error="uploadError"
     :show-file-list="false">
     <i class="el-icon-plus avatar-uploader-icon"></i>
   </el-upload>
   <quill-editor
     class="info-editor"
     v-model="content"
     ref="QuillEditor"
     :options="editorOption"
     @blur="onEditorBlur($event)"
     @focus="onEditorFocus($event)"
     @ready="onEditorReady($event)">
   </quill-editor>
 </div>
</template>
<script>
 import axios from '@/API/';
import { quillEditor } from "vue-quill-editor";
import COS from "cos-js-sdk-v5";
import Upload from '@/components/Upload.vue';
import { addQuillTitle } from '../utils/quill-title.js';

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

// 工具栏配置
 const toolbarOptions = [
['bold', 'italic', 'underline', 'strike'],    // toggled buttons
['blockquote', 'code-block'],

[{'header': 1}, {'header': 2}],        // custom button values
[{'list': 'ordered'}, {'list': 'bullet'}],
[{'script': 'sub'}, {'script': 'super'}],   // superscript/subscript
[{'indent': '-1'}, {'indent': '+1'}],     // outdent/indent
[{'direction': 'rtl'}],             // text direction

[{'size': ['small', false, 'large', 'huge']}], // custom dropdown
[{'header': [1, 2, 3, 4, 5, 6, false]}],

[{'color': []}, {'background': []}],     // dropdown with defaults from theme
[{'font': []}],
[{'align': []}],
['link', 'image', 'video'],
['clean']                     // remove formatting button
]

export default {
   data() {
     return {
     editorOption: {
     placeholder: '请输入编辑内容',
     theme: 'snow', //主题风格
     modules: {
     toolbar: {
     container: toolbarOptions, // 工具栏
     handlers: {
     'image': function (value) {
     if (value) {
     document.querySelector('#quill-upload input').click()
     } else {
     this.quill.format('image', false);
     }
     }
     }
     }
     }
     }, // 富文本编辑器配置
     content: '', //富文本内容
     }
   },
   methods: {
     // 上传图片前
     beforeUpload(res, file) {
     const isJPG = file.type === 'image/jpg' || file.type === 'image/png' || file.type === 'image/jpeg'
   const isLt1M = file.size / 1024 / 1024 < 1
   if (!isJPG) {
     this.$message.error('支持JPG、PNG格式的图片,大小不得超过1M')
   }
   if (!isLt1M) {
     this.$message.error('文件最大不得超过1M')
   }
   return isJPG && isLt1M
     },
     // 上传图片成功
     uploadSuccess(res, file) {
     let quill = this.$refs.QuillEditor.quill;
     let length = quill.getSelection().index;
     quill.insertEmbed(length, 'image', url);
     quill.setSelection(length+1)
     },
     // 上传图片失败
     uploadError(res, file) {
       this.$message.error('图片插入失败')
     },
     // 上传图片处理过程
     upload(req){}
   }
 }
</script>

<style scoped>
.avatar-uploader{
display: none;
}
</style>

2.编辑器上增加title提示

在编辑器上增加一个quill-title.js的工具栏的title的配置文件


const titleConfig = {
'ql-bold':'加粗',
'ql-color':'字体颜色',
'ql-font':'字体',
'ql-code':'插入代码',
'ql-italic':'斜体',
'ql-link':'添加链接',
'ql-background':'背景颜色',
'ql-size':'字体大小',
'ql-strike':'删除线',
'ql-script':'上标/下标',
'ql-underline':'下划线',
'ql-blockquote':'引用',
'ql-header':'标题',
'ql-indent':'缩进',
'ql-list':'列表',
'ql-align':'文本对齐',
'ql-direction':'文本方向',
'ql-code-block':'代码块',
'ql-formula':'公式',
'ql-image':'图片',
'ql-video':'视频',
'ql-clean':'清除字体样式'
};

export function addQuillTitle(){
const oToolBar = document.querySelector('.ql-toolbar'),
   aButton = oToolBar.querySelectorAll('button'),
   aSelect = oToolBar.querySelectorAll('select'),
   aSpan= oToolBar.querySelectorAll('span');
aButton.forEach((item)=>{
 if(item.className === 'ql-script'){
  item.value === 'sub' ? item.title = '下标': item.title = '上标';
 }else if(item.className === 'ql-indent'){
  item.value === '+1' ? item.title ='向右缩进': item.title ='向左缩进';
 }else if(item.className === 'ql-list'){
  item.value==='ordered' ? item.title='有序列表' : item.title='无序列表'
 }else if(item.className === 'ql-header'){
  item.value === '1' ? item.title = '标题H1': item.title = '标题H2';
 }else{
  item.title = titleConfig[item.classList[0]];
 }
});
aSelect.forEach((item)=>{
 if(item.className!='ql-color'&&item.className!='ql-background'){
  item.parentNode.title = titleConfig[item.classList[0]];
 }
});
aSpan.forEach((item)=>{
 if(item.classList[0]==='ql-color'){
  item.title = titleConfig[item.classList[0]];
 }else if(item.classList[0]==='ql-background'){
  item.title = titleConfig[item.classList[0]];
 }
});
}

在editor.vue中引入quill-title.js


<template>
 <div>
   <!-- 图片上传组件辅助-->
   <el-upload
     class="avatar-uploader"
     action=""
     accept="image/jpg, image/jpeg, image/png, image/gif"
     :http-request="upload"
     :before-upload="beforeUploadImg"
     :on-success="uploadSuccess"
     :on-error="uploadError"
     :show-file-list="false">
     <i class="el-icon-plus avatar-uploader-icon"></i>
   </el-upload>
   <quill-editor
     class="info-editor"
     v-model="content"
     ref="QuillEditor"
     :options="editorOption"
     @blur="onEditorBlur($event)"
     @focus="onEditorFocus($event)"
     @ready="onEditorReady($event)">
   </quill-editor>
 </div>
</template>
<script>
 import axios from '@/API/';
import { quillEditor } from "vue-quill-editor";
import COS from "cos-js-sdk-v5";
import Upload from '@/components/Upload.vue';
import { addQuillTitle } from '../utils/quill-title.js';

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

// 工具栏配置
 const toolbarOptions = [
['bold', 'italic', 'underline', 'strike'],    // toggled buttons
['blockquote', 'code-block'],

[{'header': 1}, {'header': 2}],        // custom button values
[{'list': 'ordered'}, {'list': 'bullet'}],
[{'script': 'sub'}, {'script': 'super'}],   // superscript/subscript
[{'indent': '-1'}, {'indent': '+1'}],     // outdent/indent
[{'direction': 'rtl'}],             // text direction

[{'size': ['small', false, 'large', 'huge']}], // custom dropdown
[{'header': [1, 2, 3, 4, 5, 6, false]}],

[{'color': []}, {'background': []}],     // dropdown with defaults from theme
[{'font': []}],
[{'align': []}],
['link', 'image', 'video'],
['clean']                     // remove formatting button
]

export default {
   data() {
     return {
     editorOption: {
     placeholder: '请输入编辑内容',
     theme: 'snow', //主题风格
     modules: {
     toolbar: {
     container: toolbarOptions, // 工具栏
     handlers: {
     'image': function (value) {
     if (value) {
     document.querySelector('#quill-upload input').click()
     } else {
     this.quill.format('image', false);
     }
     }
     }
     }
     }
     }, // 富文本编辑器配置
     content: '', //富文本内容
     }
   },
   mounted(){
   addQuillTitle();
 },
   methods: {
     // 上传图片前
     beforeUpload(res, file) {
     const isJPG = file.type === 'image/jpg' || file.type === 'image/png' || file.type === 'image/jpeg'
   const isLt1M = file.size / 1024 / 1024 < 1
   if (!isJPG) {
     this.$message.error('支持JPG、PNG格式的图片,大小不得超过1M')
   }
   if (!isLt1M) {
     this.$message.error('文件最大不得超过1M')
   }
   return isJPG && isLt1M
     },
     // 上传图片成功
     uploadSuccess(res, file) {
     let quill = this.$refs.QuillEditor.quill;
     let length = quill.getSelection().index;
     quill.insertEmbed(length, 'image', url);
     quill.setSelection(length+1)
     },
     // 上传图片失败
     uploadError(res, file) {
       this.$message.error('图片插入失败')
     },
     // 上传图片处理过程
     upload(req){}
   }
 }
</script>

<style scoped>
.avatar-uploader{
display: none;
}
</style>

补充知识:Vue引用quill富文本编辑器,图片处理的两个神器插件(quill-image-drop-module、quill-image-resize-module)的正确姿势。(解决各种报错)

一、前言

我在vue-quill-editor的Github认识了这两个插件。

quill-image-drop-module:允许粘贴图像并将其拖放到编辑器中。

quill-image-resize-module:允许调整图像大小。

都很实用呐!

然而DEMO不够详细,实际引用时,报了很多错误。

Cannot read property 'imports' of undefined"、

Failed to mount component: template or render function not defined.、

Cannot read property 'register' of undefined。

下面说一下正确的引用姿势。

二、我的环境

Webpack + Vue-Cli 2.0 (vue init非simple的版本)

三、正文

1、确保你的quill富文本编辑器(不添加插件时)可以正常运行。

2、安装NPM依赖。

cnpm install quill-image-drop-module -S

cnpm install quill-image-resize-module -S

3、在build文件夹下找到webpack.base.conf.js。

修改:


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

4、修改你在页面引用的“quill富文本组件”。

修改<script>标签内代码:


 // 以前需要有下面几行:
 import { quillEditor } from 'vue-quill-editor' //注意quillEditor必须加大括号,否则报错。
 import "quill/dist/quill.core.css";//
 import "quill/dist/quill.snow.css";

// 新增下面代码:
 import resizeImage from 'quill-image-resize-module' // 调整大小组件。
 import { ImageDrop } from 'quill-image-drop-module'; // 拖动加载图片组件。
 Quill.register('modules/imageDrop', ImageDrop);
 Quill.register('modules/resizeImage ', resizeImage )

然后,修改页面引用的:options="editorOption"。


editorOption: {
modules: {
// 新增下面
imageDrop: true, // 拖动加载图片组件。
   imageResize: { //调整大小组件。
      displayStyles: {
        backgroundColor: 'black',
        border: 'none',
        color: 'white'
      },
      modules: [ 'Resize', 'DisplaySize', 'Toolbar' ]
    }
}
}

重新 npm run dev ,插件运行成功!

来源:https://blog.csdn.net/maggie_live/article/details/88695477

标签:vue,编辑器,vue-quill-editor
0
投稿

猜你喜欢

  • Python中利用pyqt5制作指针钟表显示实时时间(指针时钟)

    2023-04-30 22:11:13
  • golang jwt+token验证的实现

    2024-05-05 09:34:04
  • python web基础之加载静态文件实例

    2023-04-22 10:09:49
  • pyecharts绘制中国2020肺炎疫情地图的实例代码

    2022-08-18 08:02:44
  • Python venv虚拟环境配置过程解析

    2021-11-30 20:21:48
  • 利用Python实现斐波那契数列的方法实例

    2022-11-07 11:20:14
  • python提取照片坐标信息的实例代码

    2023-06-01 16:37:10
  • asp如何用FileSystemObject组件来做一个站内搜索?

    2010-06-12 12:47:00
  • java代码获取数据库表里数据的总数操作

    2024-01-14 23:41:31
  • 从品牌网站看交互设计

    2009-08-18 12:39:00
  • Pycharm配置Anaconda环境的详细图文教程

    2021-10-30 00:57:23
  • springboot配置数据库密码特殊字符报错的解决

    2024-01-17 18:55:07
  • 简单谈谈mysql左连接内连接

    2024-01-13 06:54:24
  • 详解 Python中LEGB和闭包及装饰器

    2023-05-19 00:16:41
  • SQL Server内存遭遇操作系统进程压榨案例分析

    2024-01-14 06:58:51
  • python实现socket+threading处理多连接的方法

    2021-12-16 17:54:32
  • 实现一个获取元素样式的函数getStyle

    2009-02-10 10:37:00
  • python3.6、opencv安装环境搭建过程(图文教程)

    2022-03-11 16:04:44
  • Python Asyncio 库之同步原语常用函数详解

    2021-04-27 03:50:39
  • Django rstful登陆认证并检查session是否过期代码实例

    2022-11-04 16:17:15
  • asp之家 网络编程 m.aspxhome.com