wangEditor功能比较全,而且容易上手,当时本地单机玩的还不错,无奈迁移到项目报编译错误,找了很多方法都没有解决,于是痛定思痛决定换插件,在试了几款富文本插件均报错的情况下无意中尝试quill富文本,惊喜发现居然没报错,开心之余却发现它的的API不全,实现常用的功能都得自己封装,于是乎踏上漫漫踩坑之路,今天特意抽空总结下,希望能给饱受折磨的兄弟们一点帮助~~~
注意1:quill默认的图片上传方法限制图片大小,几兆的图片直接报错,
所以采用elementUI的图片上传组件将图片先上传到本地,再赋值给Qill-Editor的图片相关函数
注意2:字体样式配置,富文本工具栏配置,上面有哪些项就对应富文本上面的项,在这里可以把不需要
的富文本项去掉
modules里面对toolbar的选项可以在handlers里面添加操作函数,如图片上传,我们可以给"image"
属性添加图片上传函数,再通过参数value判断用户是否有图片上传操作,如果有,直接调用upload的
点击事件进行图片上传(后面详细介绍图片上传参数和方法)
图片上传参数配置,注意:这里是upload插件上传图片,所以参数配置还是跟elementUI的upload组件
用法一样,要配置请求头,请求地址和请求参数
注意,先测试图片上传是否成功,upload组件用法大家应该都熟悉了就不赘述,还是提醒一句,先得保证
自己本地图片上传成功再来测试在QUILL里面图片上传功能,咋们先得保证服务器图片上传没问题,如果
本地是成功的,在quill上传图片出问题排查也更容易
main.js里面的配置:
import VueQuillEditor from 'vue-quill-editor'
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'
Vue.use(VueQuillEditor);
分享完毕,以下是完整代码
<template>
<div>
<!-- 图片上传组件辅助-->
<!-- 注意quill默认的图片上传方法限制图片大小,几兆的图片直接报错,
所以采用elementUI的图片上传组件将图片先上传到本地,再赋值到Qill-Editor的图片上传函数中-->
<el-upload
class="uploaders"
multiple
:limit="5"
:action="serverUrl"
:headers="header"
:data="data"
:on-success="uploadSuccess"
:on-error="uploadError"
:before-upload="beforeUpload"
>
</el-upload>
<quill-editor
v-model="content"
ref="myQuillEditor"
:options="editorOption"
@change="onEditorChange($event)"
class="ql-snow ql-editor">
</quill-editor>
</div>
</template>
<script>
import Quill from "quill";
let fontSizeStyle = Quill.import("attributors/style/size");//引入后可以在css上写样式覆盖原来的默认字体样式
fontSizeStyle.whitelist = [ //注入whitelist样式配置 直接把富文本的默认字体设置改为以下配置,但是要结合CSS定义的类样式使用,否则字体大小设置不生效
"18px",
"20px",
"22px",
"24px",
"26px",
"28px",
"30px",
"32px"
];
Quill.register(fontSizeStyle, true);//注册定义的样式
const toolbarOptions = [
["bold", "italic", "underline"],
[{ header: 1 }, { header: 2 }],
[{ list: "ordered" }, { list: "bullet" }],
[{ indent: "-1" }, { indent: "+1" }],
[{ direction: "rtl" }],
[{ size: fontSizeStyle.whitelist }],//使用自定义的样式 注意后面CSS里面要有样式对应,否则字体大小设置不生效
[{ header: [1, 2, 3, 4, 5, 6, false] }],
[{ color: [] }],
[{ font: [] }],
[{ align: [] }],
["link", "image"]
]
export default {
props: {
editorValue: {
type: [Number, Object, Array, String],
default: ''
}
},
data() {
return {
quillUpdateImg: false, // 根据图片上传状态来确定是否显示loading动画,刚开始是false,不显示
content: null,//富文本内容
editorOption: {//富文本配置
placeholder: '',
theme: 'snow', // or 'bubble'
modules: {
toolbar: {
container: toolbarOptions,
handlers: {
'image': function (value) {
if (value) {
// 触发upload选择图片文件
document.querySelector('.uploaders input').click()
} else {
// formate('name',value) 这里是设置图片为空
this.quill.format('image', false);
}
}
}
}
}
},
serverUrl: '', // 这里写你要上传的图片服务器地址
header: { //这里是把图片上传到你项目服务器时的请求头配置
Authorization: '',//请求头的参数
TenantKey: ''//请求头的参数
},
data: { //这里是把图片上传到你项目服务器时的请求参数配置,本项目后台只需传type:4,大家根据自己的吸纳灌木配置
type: ''
},
}
},
mounted(){
this.content= this.editorValue
},
methods: {
onEditorChange({editor, html, text}) {//实时监听富文本内容改变
this.content = html
this.$emit('getSonContent', html)//这里将富文本的完整内容传给父组件
},
// 富文本图片上传前
beforeUpload() {
// 显示loading动画
this.quillUpdateImg = true
},
uploadSuccess(res, file) {//注意这里是upload的图片上传函数,
// 不是quill内部的图片上传函数,所以用法跟element的图片上传组件一致
// 获取富文本组件实例
let quill = this.$refs.myQuillEditor.quill
// 如果上传成功
if (res.resultCode == 200 ) {
// 获取光标所在位置
let length = quill.getSelection().index;
// 插入图片 res.resultData.fileUrl为服务器返回的图片地址
quill.insertEmbed(length, 'image', res.resultData.fileUrl)
// 调整光标到最后
quill.setSelection(length + 1)
} else {
this.$message.error('图片插入失败')
}
// loading动画消失
this.quillUpdateImg = false
},
// 富文本图片上传失败
uploadError() {
// loading动画消失
this.quillUpdateImg = false
this.$message.error('图片插入失败')
}
}
}
</script>
<style lang="scss" >
.uploaders{
display: none;
}
.ql-container.ql-snow {
line-height: normal !important;
height: 250px !important;
font-size: 14px;
}
.ql-snow {
.ql-tooltip[data-mode="link"]::before {
content: "请输入链接地址:";
}
.ql-tooltip.ql-editing a.ql-action::after {
border-right: 0px;
content: "保存";
padding-right: 0px;
}
.ql-tooltip[data-mode="video"]::before {
content: "请输入视频地址:";
}
.ql-picker.ql-size {
.ql-picker-label[data-value="12px"]::before,
.ql-picker-item[data-value="12px"]::before {
content: "12px";
}
.ql-picker-label[data-value="14px"]::before,
.ql-picker-item[data-value="14px"]::before {
content: "14px";
}
.ql-picker-label[data-value="16px"]::before,
.ql-picker-item[data-value="16px"]::before {
content: "16px";
}
.ql-picker-label[data-value="18px"]::before,
.ql-picker-item[data-value="18px"]::before {
content: "18px";
}
.ql-picker-label[data-value="20px"]::before,
.ql-picker-item[data-value="20px"]::before {
content: "20px";
}
.ql-picker-label[data-value="22px"]::before,
.ql-picker-item[data-value="22px"]::before {
content: "22px";
}
.ql-picker-label[data-value="24px"]::before,
.ql-picker-item[data-value="24px"]::before {
content: "24px";
}
.ql-picker-label[data-value="26px"]::before,
.ql-picker-item[data-value="26px"]::before {
content: "26px";
}
.ql-picker-label[data-value="28px"]::before,
.ql-picker-item[data-value="28px"]::before {
content: "28px";
}
.ql-picker-label[data-value="30px"]::before,
.ql-picker-item[data-value="30px"]::before {
content: "30px";
}
.ql-picker-label[data-value="32px"]::before,
.ql-picker-item[data-value="32px"]::before {
content: "32px";
}
.ql-picker-label[data-value="34px"]::before,
.ql-picker-item[data-value="34px"]::before {
content: "34px";
}
.ql-picker-label[data-value="36px"]::before,
.ql-picker-item[data-value="36px"]::before {
content: "36px";
}
}
.ql-picker.ql-header {
.ql-picker-label::before,
.ql-picker-item::before {
content: "文本";
}
.ql-picker-label[data-value="1"]::before,
.ql-picker-item[data-value="1"]::before {
content: "标题1";
}
.ql-picker-label[data-value="2"]::before,
.ql-picker-item[data-value="2"]::before {
content: "标题2";
}
.ql-picker-label[data-value="3"]::before,
.ql-picker-item[data-value="3"]::before {
content: "标题3";
}
.ql-picker-label[data-value="4"]::before,
.ql-picker-item[data-value="4"]::before {
content: "标题4";
}
.ql-picker-label[data-value="5"]::before,
.ql-picker-item[data-value="5"]::before {
content: "标题5";
}
.ql-picker-label[data-value="6"]::before,
.ql-picker-item[data-value="6"]::before {
content: "标题6";
}
.ql-picker-label[data-value="7"]::before,
.ql-picker-item[data-value="7"]::before {
content: "标题7";
}
}
.ql-picker.ql-font {
.ql-picker-label[data-value="SimSun"]::before,
.ql-picker-item[data-value="SimSun"]::before {
content: "宋体";
font-family: "SimSun" !important;
}
.ql-picker-label[data-value="SimHei"]::before,
.ql-picker-item[data-value="SimHei"]::before {
content: "黑体";
font-family: "SimHei";
}
.ql-picker-label[data-value="Microsoft-YaHei"]::before,
.ql-picker-item[data-value="Microsoft-YaHei"]::before {
content: "微软雅黑";
font-family: "Microsoft YaHei";
}
.ql-picker-label[data-value="KaiTi"]::before,
.ql-picker-item[data-value="KaiTi"]::before {
content: "楷体";
font-family: "KaiTi" !important;
}
.ql-picker-label[data-value="FangSong"]::before,
.ql-picker-item[data-value="FangSong"]::before {
content: "仿宋";
font-family: "FangSong";
}
}
}
</style>
小结:
1.图片太大建议用upload组件先将图片上传到服务器,再将数据读取赋值给quill-editor图片,否则图片太大直接上传失败
2.对于字体大小等相关配置,网上看到一些朋友说直接找到插件的whitelist属性修改,如果是本地测试可以,上线不可能还跑到依赖包文件直接找到相关代码修改,建议本地配置白名单注入,再写样式覆盖
3.注意源码末尾的关于Quill的CSS要加上,否则我们配置的字体样式设置不生效
4.图片上传先确保上传到自己项目服务器是好的,再放到quill-editor里面调试
周末抽空做了个总结,希望能帮到大家,水平有限不足之处欢迎指正~~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。