quill富文本编辑器自定义字体、文字大小(编辑器内含element上传组件)
如下是我们需要得到的文字大小和字体的效果:
自定义字体、文字大小JS部分:
//引入Qill插件 import Quill from "quill"; // 自定义字体 let fontFamily = ['SimSun', 'SimHei', 'Microsoft-YaHei', 'KaiTi', 'FangSong', 'Arial', 'pingfang']; Quill.imports['formats/font'].whitelist = fontFamily; Quill.register(Quill.imports['formats/font']) // 自定义文字大小 let fontSize = ['10px', '12px', '14px', '16px', '20px', '24px', '36px'] Quill.imports['attributors/style/size'].whitelist = fontSize; Quill.register(Quill.imports['attributors/style/size']); const toolbarOptions = [ [ "bold", "italic", "underline", "strike", "blockquote", "code-block", { header: 1 }, { header: 2 }, { list: "ordered" }, { list: "bullet" }, { indent: "-1" }, { indent: "+1" }, { script: "sub" }, // 下标 { script: "super" }, // 上标 { align: [] }, { color: [] }, { background: [] }, "link", "image", ], [{ size: fontSize }], // 文字大小 [{ header: [1, 2, 3, 4, 5, 6, false] }], // 标题 [{ font: fontFamily }], // 字体 ];
自定义字体、文字大小css部分:
::v-deep{ /* 文字大小 */ .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='10px']::before, .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='10px']::before { content: '10px'; } .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='12px']::before, .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='12px']::before { content: '12px'; } .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='14px']::before, .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='14px']::before { content: '14px'; } .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='16px']::before, .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='16px']::before { content: '16px'; } .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='20px']::before, .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='20px']::before { content: '20px'; } .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='24px']::before, .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='24px']::before { content: '24px'; } .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='36px']::before, .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='36px']::before { content: '36px'; } /* 字体 */ .ql-snow .ql-picker.ql-font .ql-picker-label[data-value='SimSun']::before, .ql-snow .ql-picker.ql-font .ql-picker-item[data-value='SimSun']::before { content: '宋体'; font-family: 'SimSun' !important; } .ql-snow .ql-picker.ql-font .ql-picker-label[data-value='SimHei']::before, .ql-snow .ql-picker.ql-font .ql-picker-item[data-value='SimHei']::before { content: '黑体'; font-family: 'SimHei'; } .ql-snow .ql-picker.ql-font .ql-picker-label[data-value='Microsoft-YaHei']::before, .ql-snow .ql-picker.ql-font .ql-picker-item[data-value='Microsoft-YaHei']::before { content: '微软雅黑'; font-family: '微软雅黑'; } .ql-snow .ql-picker.ql-font .ql-picker-label[data-value='KaiTi']::before, .ql-snow .ql-picker.ql-font .ql-picker-item[data-value='KaiTi']::before { content: '楷体'; font-family: 'KaiTi' !important; } .ql-snow .ql-picker.ql-font .ql-picker-label[data-value='FangSong']::before, .ql-snow .ql-picker.ql-font .ql-picker-item[data-value='FangSong']::before { content: '仿宋'; font-family: 'FangSong'; } .ql-snow .ql-picker.ql-font .ql-picker-label[data-value='Arial']::before, .ql-snow .ql-picker.ql-font .ql-picker-item[data-value='Arial']::before { content: 'Arial'; font-family: 'Arial'; } .ql-snow .ql-picker.ql-font .ql-picker-label[data-value='pingfang']::before, .ql-snow .ql-picker.ql-font .ql-picker-item[data-value='pingfang']::before { content: '苹方'; font-family: '苹方'; } // 设置每个字体的css字体样式 .ql-font-SimSun { font-family: 'SimSun'; } .ql-font-SimHei { font-family: 'SimHei'; } .ql-font-Microsoft-YaHei { font-family: '微软雅黑'; } .ql-font-KaiTi { font-family: 'KaiTi'; } .ql-font-FangSong { font-family: 'FangSong'; } .ql-font-Arial { font-family: 'Arial'; } .ql-font-pingfang { font-family: '苹方'; } /* 标题 */ .ql-snow .ql-picker.ql-header .ql-picker-label::before, .ql-snow .ql-picker.ql-header .ql-picker-item::before { content: "文本" !important; } .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" !important; } .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" !important; } .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" !important; } .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" !important; } .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" !important; } .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" !important; } }
组件完整代码(含element上传组件功能):
<template> <div> <el-upload id="upload" class="editor-upload" :action="uploadUrl" :data="uploadData" name="file" :headers="headers" :show-file-list="false" :on-success="uploadSuccess" :on-error="uploadError" :before-upload="beforeUpload" > el-upload> <quill-editor class="editor" v-model="content" ref="myQuillEditor" :options="editorOption" @blur="onEditorBlur($event)" @focus="onEditorFocus($event)" @change="onEditorChange($event)" > quill-editor> div> template> <script> import { mapGetters } from "vuex"; //引入Qill插件 import Quill from "quill"; // 自定义字体 let fontFamily = ['SimSun', 'SimHei', 'Microsoft-YaHei', 'KaiTi', 'FangSong', 'Arial', 'pingfang']; Quill.imports['formats/font'].whitelist = fontFamily; Quill.register(Quill.imports['formats/font']) // 自定义文字大小 let fontSize = ['10px', '12px', '14px', '16px', '20px', '24px', '36px'] Quill.imports['attributors/style/size'].whitelist = fontSize; Quill.register(Quill.imports['attributors/style/size']); const toolbarOptions = [ [ "bold", "italic", "underline", "strike", "blockquote", "code-block", { header: 1 }, { header: 2 }, { list: "ordered" }, { list: "bullet" }, { indent: "-1" }, { indent: "+1" }, { script: "sub" }, // 下标 { script: "super" }, // 上标 { align: [] }, { color: [] }, { background: [] }, "link", "image", ], [{ size: fontSize }], // 文字大小 [{ header: [1, 2, 3, 4, 5, 6, false] }], // 标题 [{ font: fontFamily }], // 字体 ]; export default { name: "Editor", data() { return { content: null, uploadUrl: process.env.VUE_APP_BASE_URL + "/pa/material/upload", headers: { Authorization: "Bearer " + this.$cookieGet("TOKEN") }, editorOption: { modules: { toolbar: { container: toolbarOptions, handlers: { // 编辑器菜单点击图片上传事件 image: function (value) { if (value) { // 调用element上传组件 document.querySelector("#upload input").click(); } }, }, }, }, }, }; }, computed: { ...mapGetters(["officialInfo"]), // 图片上传的参数 uploadData() { return { type: 1, id: this.officialInfo.id }; }, }, methods: { onEditorBlur() { this.$emit("on-blur", this.content); }, onEditorFocus() { //获得焦点事件 }, onEditorChange() { //内容改变事件 }, // 上传图片前 beforeUpload(file) { const isLt2M = file.size / 1024 / 1024 < 2; if (!isLt2M) { this.$message.error("上传图片不能大于 2M"); } }, // 上传图片成功 uploadSuccess(res, file) { if (res.code == 200) { let img = `<img src="https:${res.data.url}" />`; this.content = (this.content || "") + img; } }, // 上传图片失败 uploadError(res, file) { console.log(res); }, // 更新文本编辑器内容 upDateContent(v) { this.content = v; }, }, }; script> <style lang="scss" scoped> ::v-deep { .ql-container { height: 300px; } .editor-upload { display: none; } /* 文字大小 */ .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='10px']::before, .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='10px']::before { content: '10px'; } .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='12px']::before, .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='12px']::before { content: '12px'; } .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='14px']::before, .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='14px']::before { content: '14px'; } .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='16px']::before, .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='16px']::before { content: '16px'; } .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='20px']::before, .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='20px']::before { content: '20px'; } .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='24px']::before, .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='24px']::before { content: '24px'; } .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='36px']::before, .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='36px']::before { content: '36px'; } /* 字体 */ .ql-snow .ql-picker.ql-font .ql-picker-label[data-value='SimSun']::before, .ql-snow .ql-picker.ql-font .ql-picker-item[data-value='SimSun']::before { content: '宋体'; font-family: 'SimSun' !important; } .ql-snow .ql-picker.ql-font .ql-picker-label[data-value='SimHei']::before, .ql-snow .ql-picker.ql-font .ql-picker-item[data-value='SimHei']::before { content: '黑体'; font-family: 'SimHei'; } .ql-snow .ql-picker.ql-font .ql-picker-label[data-value='Microsoft-YaHei']::before, .ql-snow .ql-picker.ql-font .ql-picker-item[data-value='Microsoft-YaHei']::before { content: '微软雅黑'; font-family: '微软雅黑'; } .ql-snow .ql-picker.ql-font .ql-picker-label[data-value='KaiTi']::before, .ql-snow .ql-picker.ql-font .ql-picker-item[data-value='KaiTi']::before { content: '楷体'; font-family: 'KaiTi' !important; } .ql-snow .ql-picker.ql-font .ql-picker-label[data-value='FangSong']::before, .ql-snow .ql-picker.ql-font .ql-picker-item[data-value='FangSong']::before { content: '仿宋'; font-family: 'FangSong'; } .ql-snow .ql-picker.ql-font .ql-picker-label[data-value='Arial']::before, .ql-snow .ql-picker.ql-font .ql-picker-item[data-value='Arial']::before { content: 'Arial'; font-family: 'Arial'; } .ql-snow .ql-picker.ql-font .ql-picker-label[data-value='pingfang']::before, .ql-snow .ql-picker.ql-font .ql-picker-item[data-value='pingfang']::before { content: '苹方'; font-family: '苹方'; } // 设置每个字体的css字体样式 .ql-font-SimSun { font-family: 'SimSun'; } .ql-font-SimHei { font-family: 'SimHei'; } .ql-font-Microsoft-YaHei { font-family: '微软雅黑'; } .ql-font-KaiTi { font-family: 'KaiTi'; } .ql-font-FangSong { font-family: 'FangSong'; } .ql-font-Arial { font-family: 'Arial'; } .ql-font-pingfang { font-family: '苹方'; } /* 标题 */ .ql-snow .ql-picker.ql-header .ql-picker-label::before, .ql-snow .ql-picker.ql-header .ql-picker-item::before { content: "文本" !important; } .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" !important; } .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" !important; } .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" !important; } .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" !important; } .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" !important; } .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" !important; } } style>