一、效果
二、安装
npm install vue-quill-editor 和 npm install quill
三、引用
import { quillEditor } from 'vue-quill-editor' // 调用富文本编辑器
import 'quill/dist/quill.snow.css' // 富文本编辑器外部引用样式
import 'quill/dist/quill.core.css'
//import 'quill/dist/quill.bubble.css'
import * as Quill from 'quill'; // 富文本基于quill
四、代码
<quill-editor
v-model="form.content"
ref="myQuillEditor"
:options="editorOption"
@blur="onEditorBlur($event)"
>
五、定义配置项(网上有改js css样式的都不好用,这个方法是最佳方案)
let fontSizeStyle = Quill.import("attributors/style/size");
fontSizeStyle.whitelist = [
"12px",
"14px",
"16px",
"18px",
"22px",
"26px",
"30px",
"36px",
"42px",
];
Quill.register(fontSizeStyle, true);
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: fontSizeStyle.whitelist,
},
], // custom dropdown
[{ header: [1, 2, 3, 4, 5, 6, false] }],
[{ color: [] }, { background: [] }], // dropdown with defaults from theme
[{ font: [] }],
[{ align: [] }],
["link", "image"],
["clean"], // remove formatting button
];
export default {...}
六、使用
data() {
return {
imageUrl: "",//上传的图片
editorOption: {
modules: {
toolbar: {
container: toolbarOptions, // 工具栏
//上传图片
handlers: {
image: function(value) {
if (value) {
document.querySelector(".avatar-uploader input").click();
//alert("自定义图片");
} else {
this.quill.format("image", false);
}
},
},
},
},
placeholder: "请插入内容...",//默认文字
},
七、整体代码
<template>
<div>
<quill-editor
v-model="form.content"
ref="myQuillEditor"
:options="editorOption"
@blur="onEditorBlur($event)"
>
</quill-editor>
<el-upload
class="avatar-uploader"
action="/api/fileUpload"
:show-file-list="false"
:on-success="handleSuccess"
multiple
:format="['jpg', 'jpeg', 'png', 'gif']"
>
<i class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</div>
</template>
<script>
import { quillEditor } from "@/assets/js/quill/vue-quill-editor";
import "@/assets/js/quill/quill.core.css";
import "@/assets/js/quill/quill.snow.css";
import * as Quill from "quill";
let fontSizeStyle = Quill.import("attributors/style/size");
fontSizeStyle.whitelist = [
"12px",
"14px",
"16px",
"18px",
"22px",
"26px",
"30px",
"36px",
"42px",
];
Quill.register(fontSizeStyle, true);
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: fontSizeStyle.whitelist,
},
], // custom dropdown
[{ header: [1, 2, 3, 4, 5, 6, false] }],
[{ color: [] }, { background: [] }], // dropdown with defaults from theme
[{ font: [] }],
[{ align: [] }],
["link", "image"],
["clean"], // remove formatting button
];
export default {
name: "editDialog",
props: {
detailsVisinle: Boolean,
editVisible: Boolean,
form: Object,
photo: {
type: Array,
default() {
return [];
},
},
},
data() {
return {
imageUrl: "",
personList: [],
editorOption: {
modules: {
toolbar: {
container: toolbarOptions, // 工具栏
handlers: {
image: function(value) {
if (value) {
document.querySelector(".avatar-uploader input").click();
//alert("自定义图片");
} else {
this.quill.format("image", false);
}
},
},
},
},
placeholder: "请插入内容...",
},
};
},
components: {
quillEditor,
},
created() {
},
methods: {
onEditorBlur() {
//失去焦点事件
},
handleSuccess(res) {
// 获取富文本组件实例
let quill = this.$refs.myQuillEditor.quill;
// 如果上传成功
console.log(res);
if (res) {
// 获取光标所在位置
let length = quill.getSelection().index;
// 插入图片,res为服务器返回的图片链接地址
quill.insertEmbed(length, "image", this.hjip + res.body[0]);
// 调整光标到最后
quill.setSelection(length + 1);
} else {
// 提示信息,需引入Message
Message.error("图片插入失败");
}
},
/*照片 */
photoAvatarSuccess(response, file, fileList, idx) {
//上传后台返回数组格式,提交后套要求String格式,逗号分开。看需求参考
this.personList = [];
this.photo.push({
name: file.name,
url: response.body.join(","),
});
this.photo.forEach((item, index) => {
this.personList.push(item.url1);
});
},
photoAvatarRemove(file, fileList, idx) {
this.photo.forEach((item, index) => {
if (file.name == item.name) {
this.photo.splice(index, 1);
this.personList.splice(index, 1);
}
});
this.personList = [];
this.photo.forEach((item, index) => {
this.personList.push(item.url1);
});
},
dataURItoBlob(dataURI, type) {
//图片转换文件
var binary = atob(dataURI.split(",")[1]);
var array = [];
for (var i = 0; i < binary.length; i++) {
array.push(binary.charCodeAt(i));
}
return new Blob([new Uint8Array(array)], { type: type });
},
beforeAvatarUpload(file) {
const _this = this;
return new Promise((resolve) => {
const reader = new FileReader();
const image = new Image();
image.onload = (imageEvent) => {
const canvas = document.createElement("canvas");
const context = canvas.getContext("2d");
const width = image.width * 0.5;
const height = image.height * 0.5;
canvas.width = width;
canvas.height = height;
context.clearRect(0, 0, width, height);
context.drawImage(image, 0, 0, width, height);
const dataUrl = canvas.toDataURL(file.type);
const blobData = _this.dataURItoBlob(dataUrl, file.type);
resolve(blobData);
};
reader.onload = (e) => {
image.src = e.target.result;
};
reader.readAsDataURL(file);
});
},
},
};
</script>