怎么给自己的博客搭建富文本编辑器?
- 技术栈:
vue2.x
- 富文本编辑器:
vue-quill-editor
- UI框架:
elementUI
因为博客是一个学习记录的网站,所以必然会用到文本编辑器,我这里选用了vue-quill-editor
这款富文本编辑器,下面介绍一下这个编辑器的使用方法!
富文本编辑器vue-quill-editor的使用
1.首先安装vue-quill-editor
及其依赖
npm i vue-quill-editor --save
npm i quill --save
2.因为我这里是把整个编辑器作为组件,所以组件内部使用就可以了
import "quill/dist/quill.core.css";
import "quill/dist/quill.snow.css";
import "quill/dist/quill.bubble.css";
//调用富文本编辑器
import { quillEditor } from "vue-quill-editor";
3.挂载组件
// 挂载文本编辑器组件
components: {
quillEditor
},
4.template
中使用
<quill-editor ref="myQuillEditor" @change="" v-model="" :options="editorOption">
</quill-editor>
5.配置富文本编辑器的功能
data() {
return {
editorOption: {
placeholder: "请在这里输入内容",
modules: {
toolbar: {
container: [
["bold", "italic", "underline", "strike"], //加粗,斜体,下划线,删除线
["blockquote", "code-block"], //引用,代码块
[{ header: 1 }, { header: 2 }], // 标题,键值对的形式;1、2表示字体大小
[{ list: "ordered" }, { list: "bullet" }], //列表
[{ script: "sub" }, { script: "super" }], // 上下标
[{ indent: "-1" }, { indent: "+1" }], // 缩进
[{ direction: "rtl" }], // 文本方向
// [{ size: ["small", false, "large", "huge"] }], // 字体大小
// [{ header: [1, 2, 3, 4, 5, 6, false] }], //几级标题
[{ color: [] }, { background: [] }], // 字体颜色,字体背景颜色
// [{ font: [] }], //字体
[{ align: [] }], //对齐方式
["clean"], //清除字体样式
["link", "image"] //上传图片、上传视频 "link" 链接 "video" 视频
],
}
}
}
};
},
6.还要在style
里添加样式
.quill-editor {
width: 1000px;
margin: 0 auto;
height: 150px;
}
.editor {
line-height: normal !important;
height: 800px;
}
.ql-snow .ql-tooltip[data-mode='link']::before {
content: '请输入链接地址:';
}
.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: '请输入视频地址:';
}
.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: '标题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: '标题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: '标题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: '标题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: '标题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: '标题6';
}
7.与一般的输入框相同,使用v-model
绑定文本内容即可,我这里提交内容使用的是change
事件,当然你也可以使用任何想使用的事件类型.
到这里就大功告成了,看一下结果!
vue-quill-editor回显以及代码块高亮
既然我们在写文章的时候贴上了很多代码,那么查看的时候肯定要回显到页面上,并且要有代码高亮才能看,要不然白纸黑字实在是头疼,最终我们还要借助插件来实现
一.vue-quill-editor回显
我们要在需要回显的页面中添加div
,然后使用v-html
渲染数据就可以了,特别需要注意的是一定要添加ql-editor
类名,否则不会生效
<div class="ql-editort" v-html=""></div>
二.代码块高亮
1.首先安装prismjs
及其依赖
//安装prismjs
npm i prismjs
//安装prismjs的编译器插件
npm i babel-plugin-prismjs -D
2.在项目下找到babel.config.js
在module.exports
中的plugins
追加以下配置,如果原本没有plugins
可以手动添加
plugins: [
[
"prismjs",
{
languages: ["javascript", "css", "markup"],
plugins: ["line-numbers"], //配置显示行号插件
theme: "okaidia", //主题名称
css: true,
},
],
],
3.在组件中引入模块
//引入代码美化插件
import Prism from "prismjs";
4.这里有个比较难处理的是我们通过文本编辑器生成的代码结构是只有pre
标签,而这个代码高亮插件只对pre
标签嵌套code
标签起作用,有的类名必须写在code
标签上,所以我们在存进数据库之前要做一个全局替换工作.类名line-numbers
显示行号language-xxx
选择编程语言,这里我们选择js:language-js
//由于富文本编辑器生成的代码块只有pre标签,没有code标签,而前端的回显需要code标签,所以需要做处理
let newContent = blogEditerContent.replace(
/<pre class="ql-syntax" spellcheck="false">/g,
'<pre class="ql-syntax line-numbers language-js" spellcheck="false"><code class="language-js">'
);
newContent = newContent.replace(/<\/pre>/g, "</code></pre>");
5.网上有部分文章说在mounted
中添加 Prism.highlightAll()
; 但我亲测并不是很好用,所以我就用了另外一种方法,自定义插件
//引入代码美化插件
import Prism from "prismjs";
let Highlight = {};
// 自定义插件
Highlight.install = function(Vue) {
// 自定义指令 v-highlight
Vue.directive("highlight", {
// 指令所在组件的 VNode 及其子 VNode 全部更新后调用
componentUpdated: function() {
//代码美化
Prism.highlightAll();
},
});
};
export default Highlight;
6.在main.js
中引用自定义插件
//引入代码块高亮插件
import Highlight from "./assets/js/Highlight";
Vue.use(Highlight);
7.然后在第一步的div
中添加命令v-highlight
<div class="ql-editor" v-html="" v-highlight></div>
到这里就大功告成了 看下效果
vue-quill-editor结合elementUI实现图片上传
写文章避免不了要上传图片的,但是这个编辑器默认是用base64
编码方式存储的,这样的缺点就是当图片比较大时,提交后台时参数过长,可能会导致提交失败,并且数据量多起来的话,会对数据库造成很大压力,所以我们就结合elementUI
的图片上传组件,将图片上传到我们自己的图片空间,并且返回URL
存到数据库中.
1.在template
中添加upload
组件 action
填写的是我们上传服务器的接口地址
<!-- elementUI上传图片组件 -->
<el-upload class="avatar-uploader"
:action="serverUrl"
:show-file-list="false"
:on-success="handleAvatarSuccess"
:on-error="handleAvatarError"
:before-upload="beforeAvatarUpload">
</el-upload>
2.在toolbar
中添加重写上传图片方法
data() {
return {
editorOption: {
modules: {
toolbar: {
//重写图片上传事件
handlers: {
'image': function (value) {
if (value) {
// 触发input框选择图片文件
document.querySelector('.avatar-uploader input').click()
} else {
this.quill.format('image', false);
}
}
}
}
}
}
};
},
3.在upload
组件的上传成功钩子函数中进行验证与插入
//图片上传成功钩子函数
handleAvatarSuccess(res) {
// res为图片服务器返回的数据
// 获取富文本组件实例
let quill = this.$refs.myQuillEditor.quill
// 如果上传成功
if (res.sinaPath !== null) {
// 获取光标所在位置
let length = quill.selection.savedRange.index;
// 插入图片 res.info为服务器返回的图片地址
quill.insertEmbed(length, 'image', res.sinaPath)
// 调整光标到最后
quill.setSelection(length + 1)
} else {
this.$message.error('图片插入失败')
}
},
4.为了提高交互体验,在图片上传过程中添加了loading
组件
//使用el-row包裹quill-editor
<el-row v-loading="quillUpdateImg">
<quill-editor ref="myQuillEditor" @change="submitBlogEditerContent" v-model="blogEditerContent" :options="editorOption">
</quill-editor>
</el-row>
5.在图片上传前的钩子函数中添加loading
图片上传结果返回后(无论成功还是失败)移除loading
//图片上传前钩子函数
beforeAvatarUpload(file) {
// 显示loading动画
this.quillUpdateImg = true
},
//图片上传失败钩子函数
handleAvatarError() {
// loading动画消失
this.quillUpdateImg = false
this.$message.error('图片插入失败')
}
//图片上传成功钩子函数
handleAvatarSuccess(res) {
// loading动画消失
this.quillUpdateImg = false
},
到这就大功告成了,上传一张图片试试看