一、下载安装
cnpm i vue-quill-editor -S
// 可拖拽图片
cnpm i quill-image-drop-module -S
// 这两个是改变图片大小的
cnpm i quill-image-resize-module -S
二、在vue 中的vue.config.js配置
var webpack = require('webpack')
module.exports = {
// 配置富文本图片拖拽
configureWebpack: {
plugins: [
new webpack.ProvidePlugin({
'window.Quill': 'quill/dist/quill.js',
'Quill': 'quill/dist/quill.js',
})
]
}}
三、配置组件,最好将富文本编辑器封装成公共组件使用
(这里我把他封装成一个公共组件)
<template>
<div>
<!-- 图片上传组件:这里整合的是elementUI的组件-->
<el-upload class='avatar-uploader' :action='serverUrl' name='file' :headers='header' :show-file-list='false'
:on-success='uploadSuccess' :on-error='uploadError' :before-upload='beforeUpload'>
</el-upload>
<!-- 实际富文本显示区域 -->
<quill-editor class='editor' :content='content' ref='myQuillEditor' :options='editorOption'
@blur='onEditorBlur($event)' @focus='onEditorFocus($event)' @change='onEditorChange($event)'>
</quill-editor>
</div>
</template>
<script>
// 需要引入的文件
import { quillEditor } from 'vue-quill-editor'
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'
import * as Quill from 'quill'
import ImageResize from 'quill-image-resize-module' // 调整大小组件。
import { ImageDrop } from 'quill-image-drop-module'; // 拖动加载图片组件。
Quill.register('modules/imageDrop', ImageDrop)
Quill.register('modules/imageResize', ImageResize)
// 工具栏配置
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'] // 链接、图片、视频 ['link', 'image', 'video']
]
export default {
props: {
/* 编辑器的内容 */
value: {
typeof: String,
},
/* 图片大小 */
maxSize: {
type: Number,
default: 1024 * 5 // kb
}
},
components: {
quillEditor
},
data () {
return {
content: '',
quillUpdateImg: false, // 根据图片上传状态来确定是否显示loading动画,刚开始是false,不显示
editorOption: {
theme: 'snow', // or 'bubble'
placeholder: '请在这里输入...',
modules: {
toolbar: {
container: toolbarOptions,
handlers: {
// 处理图片上传
image: function (value) {
if (value) {
// 触发input框选择图片文件
document.querySelector('.avatar-uploader input').click()
} else {
this.quill.format('image', false)
}
}
}
},
// 拖拽上传和调整图片大小
imageDrop: true,
imageResize: {
displayStyles: {
backgroundColor: 'black',
border: 'none',
color: 'white'
},
modules: ['Resize', 'DisplaySize', 'Toolbar']
},
},
},
serverUrl: `${process.env.VUE_APP_BASE_API}/upload/uploadImage`, // 这里写你要上传的图片服务器地址
header: {
// token: sessionStorage.token
} // 有的图片服务器要求请求头需要有token
}
},
mounted () { },
methods: {
onEditorBlur () {
// 失去焦点事件
},
onEditorFocus () {
// 获得焦点事件
},
onEditorChange (editor) {
this.content = editor.html
// console.log(this.content);
this.$emit('changeContent', this.content)
},
// 富文本图片上传前
beforeUpload () {
// 显示loading动画
this.quillUpdateImg = true
},
uploadSuccess (res, file) {
console.log(res);
// res为图片服务器返回的数据
// 获取富文本组件实例
let quill = this.$refs.myQuillEditor.quill
// 如果上传成功
if (res.code === 200) {
// this.$message.success('图片上传成功')
// 获取光标所在位置
let length = quill.getSelection().index
// 插入图片 res.url为服务器返回的图片地址,需要拼接图片服务根地址
quill.insertEmbed(length, 'image', res.data.url)
// 调整光标到最后
quill.setSelection(length + 1)
} else {
this.$message.warning('图片插入失败')
}
// loading动画消失
this.quillUpdateImg = false
},
// 富文本图片上传失败
uploadError () {
// loading动画消失
this.quillUpdateImg = false
this.$message.warning('图片插入失败')
}
},
watch: {
value (newValue) {
// console.log(newValue);
this.content = newValue
},
},
}
</script>
<!-- 富文本样式,需要加哦,不然有问题 -->
<style>
.avatar-uploader {
height: 0;
}
.editor {
line-height: normal !important;
height: 300px;
}
.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: "14pt";
}
.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: "10pt";
}
.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: "18pt";
}
.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: "32pt";
}
.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: "等宽字体";
}