废话:
最近写博客。重新写了下文章编辑器。用的quill.js,觉得应该分享下。有些坑还是需要注意下的。
一、vue-quill-editor引入和使用
1、先放官方的一个文档地址:
https://github.surmon.me/vue-quill-editor/
npm地址:https://www.npmjs.com/package/vue-quill-editor
2、使用方式(个人推荐)
个人用的是对应的页面单独引入,而不是全局引入。全局引入会引起一些不必要的麻烦。
import { quillEditor } from 'vue-quill-editor' export default { components: { quillEditor }}
vue页面:
<quill-editor ref="QuillEditor" class="quill-dht" :options="editorOption" v-model="content" @blur="onEditorBlur($event)" @focus="onEditorFocus($event)" @ready="onEditorReady($event)" @change="onEditorChange($event)" ></quill-editor>
注意上面的几个事件,具体就不需要我来解释了吧
个人是change事件有使用,就是使用的时候大家注意节流或者防抖
事件里面关键的是返回一个对象数据,比较常用的是text字段,这个是富文本的纯文本内容,在文章的简介方面比较有用。不然v-model里面的是包含了html元素的。自己剔除多麻烦。
放一下关于我的配置项
editorOption: { theme: "snow", //注意样式问题 placeholder: "开始创作……", debug: false, modules: { // 自定义菜单栏 toolbar: { container: [ ["bold", "italic", "underline", "strike"], // toggled buttons ["blockquote", "code-block"], [{ header: 1 }, { header: 2 }], // custom button values [{ indent: "-1" }, { indent: "+1" }], // outdent/indent [{ direction: "rtl" }], // text direction [{ size: ["small", false, "large", "huge"] }], // custom dropdown [{ color: [] }, { background: [] }], // dropdown with defaults from theme [{ align: [] }], ["link", "image"], ["clean"] // remove formatting button ], //自定义按钮事件,我这里自定义了image的上传方式 handlers: { image: value => { if (value) { this.upload_type = 1; this.$refs.upload.click(); } else { this.quill.format("image", false); } } } }, // imageDrop: true, // 开启图片拖拽上传,以及自定义大小 imageResize: { displayStyles: { backgroundColor: "black", border: "none", color: "white" } }, ImageExtend: { // 如果不作设置,即{} 则依然开启复制粘贴功能且以base64插入 name: "img", // 图片参数名 size: 1, // 可选参数 图片大小,单位为M,1M = 1024kb action: uploadImg, response: res => { return this.$api.static().visit + res.data; }, headers: xhr => { xhr.setRequestHeader("Authorization", user_info.sign); }, sizeError: () => { this.$notify({ title: "上传失败", type: "error", message: "图片大小超过1M" }); }, start: () => {}, // 可选参数 自定义开始上传触发事件 end: () => {}, // 可选参数 自定义上传结束触发的事件,无论成功或者失败 // 可选参数 上传失败触发的事件 error: e => { console.log(e); this.$notify({ title: "上传失败", type: "error", message: "图片大小超过1M" }); } } } },
3、样式的引入
因为用的是vue组件所以不需要担心样式问题,但是大家注意下样式必须在全局引用。除非你打算自定义一遍按钮的事件。原因在于样式不仅仅是你在编辑器页面要用,你后面文章的浏览页面也需要使用的。
引用的话再main.js中,看你用哪个,就引用哪个。注意要和上面的配置项在对应
//import "quill/dist/quill.core.css"; import "quill/dist/quill.snow.css"; //import "quill/dist/quill.bubble.css";
4、文章编辑完毕,你需要发布,关键点,网上多数文章没有说这块
网上的常规方式是:
<section class="ql-editor" v-html="info.content"></section>
v-html里面是刚才编辑器v-model里面的内容。
但是这样用之后大家会发现,唉,我图片超出容器了。字体大小不对。样式也不一样。怎么和我编辑器的内容差别这么大。
原因:
1、你的样式没有全局引入
2、上面的方式引入方式是错误的(我上面给的官方都没有说,坑)
解决:
1、样式好解决,并且我上面提前说过了
2、html内容的格式错了
这个我其实是通过f12仔细观察编辑器的编辑的html内容发现的。
注意看图片,实际编辑器的编辑内容区域是在下面几个div内容里面的,并且很多的内容是有独立css的
上图:
所以其实正确的内容展示方式是(如果样式不对,那么就多参考下编辑器当中的样式):
<div class="ql-snow"> <section class="ql-editor" v-html="info.content"></section> </div>
基本上这样之后我的内容就和编辑器同步了,并且图片等都不会溢出
二、好用的插件介绍
1、quill-image-resize-module,支持图片在编辑的时候调整大小和位置
使用:
import { quillEditor, Quill } from "vue-quill-editor"; // 支持图片缩放 import ImageResize from "quill-image-resize-module"; Quill.register("modules/imageResize", ImageResize);
editorOption: { theme: "snow", placeholder: "开始创作……", debug: false, modules: { imageResize: { displayStyles: { backgroundColor: "black", border: "none", color: "white" } } } },
具体多看官方文档,挺简单的
2、quill-image-extend-module支持拖拽进来的图片上传到服务器
使用:
import { container, ImageExtend, QuillWatch } from "quill-image-extend-module"; Quill.register("modules/ImageExtend", ImageExtend);
我这里代码太乱了,我直接放官方地址,比看我的代码好很多
git:https://github.com/NextBoy/quill-image-extend-module
3、自定义图片上传(个人用的elementUI)
主要是工具栏配置这里
// 自定义菜单栏 toolbar: { container: [ ["bold", "italic", "underline", "strike"], // toggled buttons ["blockquote", "code-block"], [{ header: 1 }, { header: 2 }], // custom button values [{ indent: "-1" }, { indent: "+1" }], // outdent/indent [{ direction: "rtl" }], // text direction [{ size: ["small", false, "large", "huge"] }], // custom dropdown [{ color: [] }, { background: [] }], // dropdown with defaults from theme [{ align: [] }], ["link", "image"], ["clean"] // remove formatting button ], handlers: { image: value => { if (value) { this.upload_type = 1; this.$refs.upload.click(); } else { this.quill.format("image", false); } } } },
elementUI部分
<el-upload :headers="headers" :action="uploadImg" :show-file-list="false" :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload" > <div ref="upload"></div> </el-upload>
主要是图片上传成功之后:
// 获取光标所在位置 let length = quill.getSelection().index; // 插入图片,res为服务器返回的图片链接地址 quill.insertEmbed( length, "image", this.$api.static().visit + res.data ); // 调整光标到最后 quill.setSelection(length + 1);
三、致谢
感谢quill富文本编辑器,虽然个人也尝试过开发。但是别人比你好,你不得不承认。