原文:https://www.jianshu.com/p/9e4e4d955d0f
就是要一个富文本编辑器,然后有图片上传功能,因为vue-quill-editor是将图片转为base64编码,所以当图片比较大时,提交后台时参数过长,导致提交失败。
解决思路
将图片先上传至服务器,再将图片链接插入到富文本中
图片上传的话可以使用element或者iview,这里我以iview举例
图片上传区域要隐藏,自定义vue-quill-editor的图片上传,点击图片上传时调用iview或者element的图片上传,上传成功后在富文本编辑器中显示图片
步骤
零、安装使用
npm install vue-quill-editor --save
main.js
import VueQuillEditor from 'vue-quill-editor'
Vue.use(VueQuillEditor);
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
html:
js:
html:
css:
.ivu-upload {
display: none;
}
js:
data () {
return {
content: '',
editorOption: {
modules: {
toolbar: {
container: toolbarOptions, // 工具栏
handlers: {
'image': function (value) {
if (value) {
// 调用iview图片上传
document.querySelector('.ivu-upload .ivu-btn').click()
} else {
this.quill.format('image', false);
}
}
}
}
}
}
}
},
methods: {
handleSuccess (res) {
// 获取富文本组件实例
let quill = this.$refs.QuillEditor.quill
// 如果上传成功
if (res) {
// 获取光标所在位置
let length = quill.getSelection().index;
// 插入图片,res为服务器返回的图片链接地址
quill.insertEmbed(length, 'image', res)
// 调整光标到最后
quill.setSelection(length + 1)
} else {
// 提示信息,需引入Message
Message.error('图片插入失败')
}
},
}
三、假如需要多个富文本编辑器
可能不止一处地方用到,比如添加完成后还有编辑功能,那就复制一份文件上传和富文本编辑:两个富文本用不同的ref标记,在各自配置中调用各自的文件上传;文件上传成功也使用不同的方法名称,里面调用各自的富文本编辑器。
重点:富文本和文件上传不管使用类名还是什么方式区分的,这两处地方都要和之前区分开。
和图片上传相同,不同的是上传文件。解决的思路也相同:在vue-quill-editor中自定义按钮,点击使用iView的文件上传,然后将地址赋值给a标签的href属性,插入到富文本光标处。
步骤
我想通过download属性自定义文件下载名称,但是两种方式都失败了,可以忽略相关代码。以下是为富文本自定义插入a链接
import { Quill } from 'vue-quill-editor';
// 自定义插入a链接
var Link = Quill.import('formats/link');
class FileBlot extends Link { // 继承Link Blot
static create(value) {
let node = undefined
if (value&&!value.href){ // 适应原本的Link Blot
node = super.create(value);
}
else{ // 自定义Link Blot
node = super.create(value.href);
// node.setAttribute('download', value.innerText); // 左键点击即下载
node.innerText = value.innerText;
node.download = value.innerText;
}
return node;
}
}
FileBlot.blotName = 'link';
FileBlot.tagName = 'A';
Quill.register(FileBlot);
配置工具栏,添加了一个upload,其余不需要的都可以去掉
自定义文件上传的图标样式
.ql-snow.ql-toolbar .ql-upload{
background: url("../assets/images/icon-upload.svg");
background-size: 16px 16px;
background-position: center center;
background-repeat:no-repeat;
/*background: red;*/
}
为两个图片上传分别定义了类名,以做调用时的区分。
修改工具栏配置,当点击富文本时,调用相应的上传组件
handlers: {
'image': (value => {
if (value) {
document.querySelector('.uploadImage input').click()
}else {
this.quill.format('image', false);
}
}),
'upload': (value => {
if (value) {
document.querySelector('.uploadFile input').click()
}
})
}
这两个文件上传都要隐藏
.uploadImage,
.uploadFile{
width: 0;
height: 0;
display: none;
}
下面是插入图片和文件的方法
methods: {
// 图片
handleSuccess (res, file) {
let quill = this.$refs.QuillEditor.quill
let length = quill.getSelection().index;
quill.insertEmbed(length, 'image', res)
quill.setSelection(length + 1)
},
// 文件
handleFileSuccess (res, file) {
let fileNameLength = file.name.length
// 插入链接
let quill = this.$refs.QuillEditor.quill
let length = quill.getSelection().index;
quill.insertEmbed(length, 'link', {href:res, innerText:file.name}, "api")
quill.setSelection(length + fileNameLength)
},
}
bug及优化
不知道为什么,百度都搜不到,好像只有我出现了这个问题,最后通过监听回车,手动换行并在换行后加了一个空格,因为没有内容的时候光标不显示,然后把光标向前调一个位置,移到空格前面。
const bindings = {
custom: {
key: 13,
handler: function(range, context) {
this.quill.insertText(range.index, '\n ');
setTimeout(() => {
let nowRange = this.quill.getSelection().index - 1
this.quill.setSelection(nowRange)
}, 0)
}
},
}
export default {
data () {
return {
content: '',
editorOption: {
modules: {
keyboard: {
bindings: bindings
},
toolbar: {
// ...
}
}
}
}
}
}
// 标题
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':'清除字体样式',
'ql-upload':'文件'
};
methods: {
addQuillTitle () {
const oToolBar = document.querySelector('.ql-toolbar'),
aButton = oToolBar.querySelectorAll('button'),
aSelect = oToolBar.querySelectorAll('select');
aButton.forEach(function(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{
item.title = titleConfig[item.classList[0]];
}
});
aSelect.forEach(function(item){
item.parentNode.title = titleConfig[item.classList[0]];
});
},
},
mounted () {
this.addQuillTitle()
},
有个需要注意的地方,按上面的方法使用后,确实有效,但是字体颜色和背景颜色的提示都变成了背景颜色,然后修改了标题栏的配置,提示才彼此对应。
const toolbarOptions = [
[{'color': []}, {'background': []}],
]
修改为
const toolbarOptions = [
[{'color': []}],
[{'background': []}],
]
图片样式限制宽高和边距就可以了,在富文本编辑器里面可以回车换行;
方式一:
可以另写一个style标签里面写上样式,也可以在原有的样式中通过深度选择器来写样式
方式二:
完全以原来的样式显示富文本