直接上源碼
<template>
? <div>
? ? <el-upload
? ? ? :action="uploadUrl"
? ? ? :before-upload="handleBeforeUpload"
? ? ? :on-success="handleUploadSuccess"
? ? ? :on-error="handleUploadError"
? ? ? name="file"
? ? ? :show-file-list="false"
? ? ? style="display: none"
? ? ? ref="upload"
? ? ? v-if="this.type == 'url'"
? ? >
? ? </el-upload>
? ? <div class="editor" ref="editor" :style="styles"></div>
? </div>
</template>
<script>
import Quill from "quill";
import "quill/dist/quill.core.css";
import "quill/dist/quill.snow.css";
import "quill/dist/quill.bubble.css";
// import { getToken } from '@/utils/auth' //如果你的接口需要token的話打開(kāi)這行
import { uploadUrl } from '@/config/env';
放在 init里面有時(shí)初始化會(huì)失效 直接放在最外面
? const Parchment = Quill.import("parchment");
? class lineHeightAttributor extends Parchment.Attributor.Class {}
? const lineHeightStyle = new lineHeightAttributor(
? ? "lineheight",
? ? "ql-lineheight",
? ? {
? ? ? scope: Parchment.Scope.INLINE,
? ? ? whitelist: ["", "1", "1-5", "1-75", "2", "3", "4", "5"],
? ? }
? );
? Quill.register({ "formats/lineHeight": lineHeightStyle }, true);
export default {
? name: "Editor",
? props: {
? ? /* 編輯器的內(nèi)容 */
? ? value: {
? ? ? type: String,
? ? ? default: "",
? ? },
? ? /* 高度 */
? ? height: {
? ? ? type: Number,
? ? ? default: null,
? ? },
? ? /* 最小高度 */
? ? minHeight: {
? ? ? type: Number,
? ? ? default: null,
? ? },
? ? /* 只讀 */
? ? readOnly: {
? ? ? type: Boolean,
? ? ? default: false,
? ? },
? ? // 上傳文件大小限制(MB)
? ? fileSize: {
? ? ? type: Number,
? ? ? default: 5,
? ? },
? ? /* 類(lèi)型(base64格式谣殊、url格式) */
? ? type: {
? ? ? type: String,
? ? ? default: "url",
? ? }
? },
? data() {
? ? return {
? ? ? uploadUrl, // 上傳的圖片服務(wù)器地址
? ? ? Quill: null,
? ? ? currentValue: "",
? ? ? options: {
? ? ? ? theme: "snow",
? ? ? ? bounds: document.body,
? ? ? ? debug: "warn",
? ? ? ? modules: {
? ? ? ? ? // 工具欄配置
? ? ? ? ? toolbar: [
? ? ? ? ? ? ["bold", "italic", "underline", "strike"], ? ? ? // 加粗 斜體 下劃線 刪除線
? ? ? ? ? ? ["blockquote", "code-block"], ? ? ? ? ? ? ? ? ? ?// 引用 ?代碼塊
? ? ? ? ? ? [{ list: "ordered" }, { list: "bullet" }], ? ? ? // 有序燥狰、無(wú)序列表
? ? ? ? ? ? [{ indent: "-1" }, { indent: "+1" }], ? ? ? ? ? ?// 縮進(jìn)
? ? ? ? ? ? [{ size: ["small", false, "large", "huge"] }], ? // 字體大小
? ? ? ? ? ? [{ header: [1, 2, 3, 4, 5, 6, false] }], ? ? ? ? // 標(biāo)題
? ? ? ? ? ? [{ color: [] }, { background: [] }], ? ? ? ? ? ? // 字體顏色竭鞍、字體背景顏色
? ? ? ? ? ? [{ align: [] }], ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 對(duì)齊方式
? ? ? ? ? ? ["clean"], ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 清除文本格式
? ? ? ? ? ? ["link", "image", "video"], ? ? ? ? ? ? ? ? ? ? ?// 鏈接、圖片必搞、視頻
? ? ? ? ? ? [{ lineheight: ["", "1", "1-5", "1-75", "2", "3", "4", "5"] }], //行高
? ? ? ? ? ],
? ? ? ? },
? ? ? ? placeholder: "請(qǐng)輸入內(nèi)容",
? ? ? ? readOnly: this.readOnly,
? ? ? },
? ? };
? },
? computed: {
? ? styles() {
? ? ? let style = {};
? ? ? if (this.minHeight) {
? ? ? ? style.minHeight = `${this.minHeight}px`;
? ? ? }
? ? ? if (this.height) {
? ? ? ? style.height = `${this.height}px`;
? ? ? }
? ? ? return style;
? ? },
? },
? watch: {
? ? value: {
? ? ? handler(val) {
? ? ? ? if (val !== this.currentValue) {
? ? ? ? ? this.currentValue = val === null ? "" : val;
? ? ? ? ? if (this.Quill) {
? ? ? ? ? ? this.Quill.pasteHTML(this.currentValue);
? ? ? ? ? }
? ? ? ? }
? ? ? },
? ? ? immediate: true,
? ? },
? },
? mounted() {
? ? this.init();
? },
? beforeDestroy() {
? ? this.Quill = null;
? },
? methods: {
? ? init() {
? ? ? const editor = this.$refs.editor;
? ? ? this.Quill = new Quill(editor, this.options);
? ? ? // 如果設(shè)置了上傳地址則自定義圖片上傳事件
? ? ? if (this.type == 'url') {
? ? ? ? let toolbar = this.Quill.getModule("toolbar");
? ? ? ? toolbar.addHandler("image", (value) => {
? ? ? ? ? this.uploadType = "image";
? ? ? ? ? if (value) {
? ? ? ? ? ? this.$refs.upload.$children[0].$refs.input.click();
? ? ? ? ? } else {
? ? ? ? ? ? this.quill.format("image", false);
? ? ? ? ? }
? ? ? ? });
? ? ? }
? ? ? //禁用編輯器,防止頁(yè)面自動(dòng)滾動(dòng)到編輯器位置
? ? ? this.Quill.enable(false);
? ? ? // 編輯器綁定內(nèi)容囊咏,如修改的時(shí)候原有的內(nèi)容
? ? ? this.Quill.pasteHTML(this.currentValue);
? ? ? setTimeout(() => {
? ? ? ? this.Quill.blur();
? ? ? ? this.Quill.enable(true);
? ? ? }, 1500); ? ? ?this.Quill.on("text-change", (delta, oldDelta, source) => {
? ? ? ? const html = this.$refs.editor.children[0].innerHTML;
? ? ? ? const text = this.Quill.getText();
? ? ? ? const quill = this.Quill;
? ? ? ? this.currentValue = html;
? ? ? ? this.$emit("input", html);
? ? ? ? this.$emit("on-change", { html, text, quill });
? ? ? });
? ? ? this.Quill.on("text-change", (delta, oldDelta, source) => {
? ? ? ? this.$emit("on-text-change", delta, oldDelta, source);
? ? ? });
? ? ? this.Quill.on("selection-change", (range, oldRange, source) => {
? ? ? ? this.$emit("on-selection-change", range, oldRange, source);
? ? ? });
? ? ? this.Quill.on("editor-change", (eventName, ...args) => {
? ? ? ? this.$emit("on-editor-change", eventName, ...args);
? ? ? });
? ? },
? ? // 上傳前校檢格式和大小
? ? handleBeforeUpload(file) {
? ? ? if (this.fileSize) {
? ? ? ? const isLt = file.size / 1024 / 1024 < this.fileSize;
? ? ? ? if (!isLt) {
? ? ? ? ? this.$message.error(`上傳文件大小不能超過(guò) ${this.fileSize} MB!`);
? ? ? ? ? return false;
? ? ? ? }
? ? ? }
? ? ? return true;
? ? },
? ? handleUploadSuccess(res, file) {
? ? ? // 獲取富文本組件實(shí)例
? ? ? let quill = this.Quill;
? ? ? // 如果上傳成功
? ? ? if (res.code == "001") {
? ? ? ? // 獲取光標(biāo)所在位置
? ? ? ? let length = quill.getSelection().index;
? ? ? ? // 插入圖片 ?res.url為服務(wù)器返回的圖片地址
? ? ? ? quill.insertEmbed(length, "image", res.data);
? ? ? ? // 調(diào)整光標(biāo)到最后
? ? ? ? quill.setSelection(length + 1);
? ? ? } else {
? ? ? ? this.$message.error("圖片插入失敗");
? ? ? }
? ? },
? ? handleUploadError() {
? ? ? this.$message.error("圖片插入失敗");
? ? },
? },
};
</script>
<style>
.editor,
.ql-toolbar {
? white-space: pre-wrap !important;
? line-height: normal !important;
}
.quill-img {
? display: none;
}
.ql-snow .ql-tooltip[data-mode="link"]::before {
? content: "請(qǐng)輸入鏈接地址:";
}
.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: "請(qǐng)輸入視頻地址:";
}
.ql-snow .ql-picker.ql-size .ql-picker-label::before,
.ql-snow .ql-picker.ql-size .ql-picker-item::before {
? content: "14px";
}
.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: "10px";
}
.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: "18px";
}
.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: "32px";
}
.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: "標(biāo)題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: "標(biāo)題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: "標(biāo)題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: "標(biāo)題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: "標(biāo)題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: "標(biāo)題6";
}
.ql-snow .ql-picker.ql-font .ql-picker-label::before,
.ql-snow .ql-picker.ql-font .ql-picker-item::before {
? content: "標(biāo)準(zhǔn)字體";
}
.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: "等寬字體";
}
.ql-snow .ql-picker.ql-lineheight .ql-picker-label::before,
.ql-snow .ql-picker.ql-lineheight .ql-picker-item::before {
? content: "行高";
}
.ql-snow .ql-picker.ql-lineheight .ql-picker-label[data-value="1"]::before,
.ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value="1"]::before {
? content: "1";
}
.ql-snow .ql-picker.ql-lineheight .ql-picker-label[data-value="1-5"]::before,
.ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value="1-5"]::before {
? content: "1.5";
}
.ql-snow .ql-picker.ql-lineheight .ql-picker-label[data-value="1-75"]::before,
.ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value="1-75"]::before {
? content: "1.75";
}
.ql-snow .ql-picker.ql-lineheight .ql-picker-label[data-value="2"]::before,
.ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value="2"]::before {
? content: "2";
}
.ql-snow .ql-picker.ql-lineheight .ql-picker-label[data-value="3"]::before,
.ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value="3"]::before {
? content: "3";
}
.ql-snow .ql-picker.ql-lineheight .ql-picker-label[data-value="4"]::before,
.ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value="4"]::before {
? content: "4";
}
.ql-snow .ql-picker.ql-lineheight .ql-picker-label[data-value="5"]::before,
.ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value="5"]::before {
? content: "5";
}
.ql-snow .ql-picker.ql-lineheight {
? width: 70px;
}
.ql-snow .ql-editor .ql-lineheight-1 {
? line-height: 1;
}
.ql-snow .ql-editor .ql-lineheight-1-5 {
? line-height: 1.5;
}
.ql-snow .ql-editor .ql-lineheight-1-75 {
? line-height: 1.75;
}
.ql-snow .ql-editor .ql-lineheight-2 {
? line-height: 2;
}
.ql-snow .ql-editor .ql-lineheight-3 {
? line-height: 3;
}
.ql-snow .ql-editor .ql-lineheight-4 {
? line-height: 4;
}
.ql-snow .ql-editor .ql-lineheight-5 {
? line-height: 5;
}
</style>