基于 Vue2+Quill 的富文本编辑器全方案:能力实现与样式优化
在 Web 开发中,富文本编辑器是内容管理系统、博客平台等应用的核心组件。本文将详细介绍如何基于 Vue 和 Quill
构建一个功能完善、样式精美的富文本编辑器,重点解决字体字号选项冗长、样式不美观及功能完整性问题,提供可直接部署使用的完整方案。
一、方案概述
本方案基于 Vue 2.x 和 Quill 编辑器,实现了以下核心功能:
- 完整的字体体系(中文字体 + 英文字体)
- 丰富的字号选择(8px-64px)
- 优化的 UI 设计,解决原生 Quill 样式简陋问题
- 图片 / 视频上传功能
- Markdown 快捷操作支持
- 响应式布局适配
为什么选择 Quill?相比其他编辑器(如 TinyMCE、CKEditor),Quill 具有轻量、可扩展性强、API 友好等特点,非常适合需要自定义功能的场景。
二、环境准备与依赖安装
2.1 基础环境
- Node.js (v14+)
- Vue CLI (可选,用于快速创建项目)
- Vue 2.x (当前 vue-quill-editor 对 Vue 3 支持有限)
2.2 依赖安装
# 安装核心编辑器
npm install vue-quill-editor --save
# 安装Quill本体
npm install quill --save
# 安装Markdown快捷键插件
npm install quill-markdown-shortcuts --save
# 安装图片上传扩展模块
npm install quill-image-super-solution-module --save
三、组件封装
<
template>
<div class=
"quill-editor-container">
<
!-- 富文本编辑器主体 -->
<quill-editor v-model="content" ref="myQuillEditor" :options="editorOption" class=
"editor"
@input="handleContentChange">
<
/quill-editor>
<
!-- 视频上传隐藏输入框 -->
<input type="file" id="video-upload-input" accept="video/*" style="display: none" @change="handleVideoUpload" />
<
/div>
<
/template>
<script>
// 引入Quill编辑器样式
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'
// 引入Vue-Quill编辑器组件和Quill核心库
import { quillEditor, Quill
} from 'vue-quill-editor'
// 引入Markdown快捷操作插件
import MarkdownShortcuts from 'quill-markdown-shortcuts'
// 引入图片上传扩展模块
import { container, ImageExtend, QuillWatch
} from "quill-image-super-solution-module"
// 引入HTTP请求工具
import request from "@/utils/request"
// 引入图片处理混入
import imageMixin from "@/mixins/imageMixin"
// 注册Markdown快捷键模块
Quill.register('modules/markdownShortcuts', MarkdownShortcuts)
// 注册图片扩展模块
Quill.register('modules/ImageExtend', ImageExtend)
// 字体配置
const fonts = [
'SimSun', 'SimHei', 'Microsoft-YaHei', 'KaiTi', 'FangSong',
'YouYuan', 'LiSu', 'STSong', 'STZhongsong', 'STKaiti',
'STFangsong', 'Arial', 'Times-New-Roman', 'Courier-New', 'Verdana',
'Georgia', 'Impact', 'Comic-Sans-MS', 'sans-serif', 'serif', 'monospace'
]
const Font = Quill.import('formats/font')
Font.whitelist = fonts
Font.format = function (node, value) {
if (value) {
fonts.forEach(font => node.classList.remove(`ql-font-${font
}`));
node.classList.add(`ql-font-${value
}`);
} else {
fonts.forEach(font => node.classList.remove(`ql-font-${font
}`));
}
};
Quill.register(Font, true)
// 字号配置
const sizes = [
'8px', '10px', '12px', '14px', '16px', '18px',
'20px', '22px', '24px', '26px', '28px',
'30px', '32px', '36px', '40px', '48px', '56px', '64px'
]
const Size = Quill.import('formats/size')
Size.whitelist = sizes
Quill.register(Size, true)
// 自定义视频Blot
const VideoBlot = Quill.import('formats/video')
const ATTRIBUTES = ['height', 'width', 'controls']
if (!Quill.imports['formats/custom-video']) {
class CustomVideoBlot extends VideoBlot {
static formats(domNode) {
return ATTRIBUTES.reduce((formats, attribute) =>
{
if (domNode.hasAttribute(attribute)) {
formats[attribute] = domNode.getAttribute(attribute)
}
return formats
}, {
})
}
format(name, value) {
if (ATTRIBUTES.includes(name)) {
if (value) {
this.domNode.setAttribute(name, value)
} else {
this.domNode.removeAttribute(name)
}
} else {
super.format(name, value)
}
}
}
CustomVideoBlot.blotName = 'custom-video'
CustomVideoBlot.tagName = 'VIDEO'
Quill.register(CustomVideoBlot)
}
export default {
name: 'RichTextEditor', // 组件名称,用于注册和引用
mixins: [imageMixin],
components: { quillEditor
},
props: {
// 接收外部传入的内容,实现双向绑定
value: {
type: String,
default: ''
},
// 编辑器高度
height: {
type: Number,
default: 500
},
// 图片上传接口地址
imageUploadUrl: {
type: String,
default: '/api/v1/cos/batch/upload/article'
},
// 视频上传接口地址
videoUploadUrl: {
type: String,
default: '/cos/batch/upload/video'
},
// 最大图片大小(MB)
maxImageSize: {
type: Number,
default: 2
},
// 最大视频大小(MB)
maxVideoSize: {
type: Number,
default: 50
}
},
data() {
return {
content: this.value, // 内部维护的内容状态
uploadedImages: [], // 已上传图片列表
uploadedVideos: [], // 已上传视频列表
editorOption: {
theme: 'snow',
modules: {
markdownShortcuts: {
},
ImageExtend: {
loading: true,
name: 'files',
size: this.maxImageSize,
action: this.imageUploadUrl,
accept: 'image/jpg, image/png, image/gif, image/jpeg, image/bmp, image/x-icon',
response: (res) =>
{
const imageUrl = res.data[0]
this.uploadedImages.push(imageUrl)
// 触发图片上传成功事件
this.$emit('image-uploaded', imageUrl)
return this.getImageUrl(imageUrl)
},
headers: (xhr) =>
{
const token = localStorage.getItem('token') || ''
if (token) {
xhr.setRequestHeader('Authorization', `Bearer ${token
}`)
}
},
sizeError: () =>
{
this.$message.error(`图片大小不能超过 ${
this.maxImageSize
}MB!`)
},
error: (err) =>
{
this.$message.error('图片上传失败,请重试')
this.$emit('upload-error', { type: 'image', error: err
})
console.error('图片上传错误:', err)
},
change: (xhr, formData) =>
{
formData.append('type', 'article')
}
},
toolbar: {
container: [
[{
'font': fonts
}],
[{
'size': sizes
}],
['bold', 'italic', 'underline', 'strike'],
[{
'color': []
}, {
'background': []
}],
[{
'script': 'sub'
}, {
'script': 'super'
}],
[{
'header': 1
}, {
'header': 2
}],
[{
'list': 'ordered'
}, {
'list': 'bullet'
}],
[{
'indent': '-1'
}, {
'indent': '+1'
}],
[{
'align': []
}],
['link', 'image', 'video'],
['blockquote', 'code-block'],
['clean']
],
handlers: {
'image': function () {
QuillWatch.emit(this.quill.id)
},
'video': function () {
document.getElementById('video-upload-input').click()
}
}
}
}
}
}
},
watch: {
// 监听外部传入的value变化,同步到组件内部
value(newVal) {
if (newVal !== this.content) {
this.content = newVal
}
},
// 监听高度变化,更新编辑器样式
height(newVal) {
this.$nextTick(() =>
{
const editorEl = this.$el.querySelector('.editor')
if (editorEl) {
editorEl.style.minHeight = `${newVal
}px`
}
})
}
},
methods: {
// 内容变化时触发,向父组件传递最新内容
handleContentChange() {
this.$emit('input', this.content)
this.$emit('change', this.content)
},
// 处理视频上传
async handleVideoUpload(e) {
const file = e.target.files[0]
if (!file) return
// 验证视频文件
if (!this.validateVideoFile(file)) {
e.target.value = ''
return
}
// 显示加载中
const loading = this.$loading({
lock: true,
text: '视频上传中,请稍候...',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
try {
const formData = new FormData()
formData.append('files', file)
// 上传视频
const res = await request({
url: this.videoUploadUrl,
method: 'post',
data: formData,
headers: {
'Content-Type': 'multipart/form-data'
}
})
if (!res || !res.data || res.data.length === 0) {
throw new Error('视频上传失败,返回格式不正确')
}
// 处理上传结果
const videoUrl = res.data[0]
this.uploadedVideos.push(videoUrl)
this.$emit('video-uploaded', videoUrl)
// 将视频插入编辑器
const quill = this.$refs.myQuillEditor.quill
const range = quill.getSelection()
const insertIndex = range ? range.index : quill.getLength() - 1
quill.insertEmbed(insertIndex, 'custom-video', this.getImageUrl(videoUrl))
// 设置视频属性
this.$nextTick(() =>
{
const lastIndex = quill.getLength() - 1
const [videoBlot] = quill.getLine(lastIndex)
if (videoBlot && videoBlot.statics.blotName === 'custom-video') {
videoBlot.format('controls', 'controls')
videoBlot.format('width', '100%')
videoBlot.format('height', 'auto')
}
quill.setSelection(lastIndex + 1)
})
this.$message.success('视频上传成功')
} catch (error) {
console.error('视频上传错误详情:', error)
this.$message.error(`视频上传失败: ${error.message || '未知错误'
}`)
this.$emit('upload-error', { type: 'video', error: error
})
} finally {
loading.close()
e.target.value = '' // 重置输入框,允许重复上传同一文件
}
},
// 验证视频文件格式和大小
validateVideoFile(file) {
const videoTypes = ['video/mp4', 'video/ogg', 'video/webm', 'video/avi', 'video/mov']
if (!videoTypes.includes(file.type)) {
this.$message.error('请上传支持的视频格式(MP4、OGG、WEBM、AVI、MOV)')
return false
}
const maxSizeBytes = this.maxVideoSize * 1024 * 1024
if (file.size > maxSizeBytes) {
this.$message.error(`视频大小不能超过 ${
this.maxVideoSize
}MB`)
return false
}
return true
},
// 获取编辑器实例
getEditorInstance() {
return this.$refs.myQuillEditor.quill
},
// 清空编辑器内容
clearContent() {
this.content = ''
this.$emit('input', '')
},
// 获取已上传的媒体文件列表
getUploadedFiles() {
return {
images: [...this.uploadedImages],
videos: [...this.uploadedVideos]
}
}
}
}
<
/script>
<style scoped>
.quill-editor-container {
width: 100%;
box-sizing: border-box;
}
.editor {
min-height: 500px;
}
::v-deep .ql-container {
min-height: 400px !important;
border: 1px solid #e5e7eb !important;
border-radius: 0 0 6px 6px;
}
::v-deep .ql-toolbar {
border: 1px solid #e5e7eb !important;
border-bottom: none !important;
border-radius: 6px 6px 0 0;
background-color: #f9fafb;
}
::v-deep .ql-editor img,
::v-deep .ql-editor video {
max-width: 100%;
height: auto;
margin: 10px 0;
}
::v-deep .ql-editor video {
min-height: 300px;
border: 1px solid #eee;
}
<
/style>
<style>
.ql-snow .ql-picker.ql-font {
width: 140px;
margin-right: 8px;
height: 30px;
display: flex;
align-items: center;
}
/* 字号选择器样式优化 */
.ql-snow .ql-picker.ql-size {
width: 80px;
margin-right: 8px;
height: 30px;
display: flex;
align-items: center;
}
/* 下拉菜单容器优化 - 解决选项过多问题 */
.ql-snow .ql-picker.ql-font .ql-picker-options {
max-height: 280px;
overflow-y: auto;
border-radius: 6px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
border: 1px solid #e2e8f0;
padding: 4px 0;
width: 140px;
}
.ql-snow .ql-picker.ql-size .ql-picker-options {
max-height: 280px;
overflow-y: auto;
border-radius: 6px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
border: 1px solid #e2e8f0;
padding: 4px 0;
width: 80px;
}
/* 滚动条美化 */
.ql-snow .ql-picker-options::-webkit-scrollbar {
width: 6px;
}
.ql-snow .ql-picker-options::-webkit-scrollbar-track {
background: #f1f5f9;
border-radius: 3px;
}
.ql-snow .ql-picker-options::-webkit-scrollbar-thumb {
background: #cbd5e1;
border-radius: 3px;
}
.ql-snow .ql-picker-options::-webkit-scrollbar-thumb:hover {
background: #94a3b8;
}
/* 下拉菜单项样式优化 */
.ql-snow .ql-picker-item {
height: 30px;
line-height: 30px;
padding: 0 12px;
transition: all 0.2s ease;
white-space: nowrap;
}
.ql-snow .ql-picker-item:hover {
background-color: #f1f5f9;
padding-left: 14px;
}
.ql-snow .ql-picker-item.ql-selected {
background-color: #e0f2fe;
color: #0284c7;
font-weight: 500;
}
/* 选择器按钮样式 */
.ql-snow .ql-picker-label {
height: 32px;
line-height: 32px;
padding: 0 8px;
border-radius: 4px;
transition: background-color 0.2s;
}
.ql-snow .ql-picker-label:hover {
background-color: #f8fafc;
}
/* 字体样式定义 - 确保生效 */
.ql-editor {
font-size: 16px;
line-height: 1.6;
}
/* 中文字体样式 */
.ql-editor .ql-font-SimSun {
font-family: "SimSun", "宋体", serif !important;
}
.ql-editor .ql-font-SimHei {
font-family: "SimHei", "黑体", sans-serif !important;
}
.ql-editor .ql-font-Microsoft-YaHei {
font-family: "Microsoft YaHei", "微软雅黑", sans-serif !important;
}
.ql-editor .ql-font-KaiTi {
font-family: "KaiTi", "楷体", serif !important;
}
.ql-editor .ql-font-FangSong {
font-family: "FangSong", "仿宋", serif !important;
}
.ql-editor .ql-font-YouYuan {
font-family: "YouYuan", "幼圆", sans-serif !important;
}
.ql-editor .ql-font-LiSu {
font-family: "LiSu", "隶书", serif !important;
}
.ql-editor .ql-font-STSong {
font-family: "STSong", "宋体-繁", serif !important;
}
.ql-editor .ql-font-STZhongsong {
font-family: "STZhongsong", "中宋-繁", serif !important;
}
.ql-editor .ql-font-STKaiti {
font-family: "STKaiti", "楷体-繁", serif !important;
}
.ql-editor .ql-font-STFangsong {
font-family: "STFangsong", "仿宋-繁", serif !important;
}
/* 英文字体样式 */
.ql-editor .ql-font-Arial {
font-family: "Arial", sans-serif !important;
}
.ql-editor .ql-font-Times-New-Roman {
font-family: "Times New Roman", serif !important;
}
.ql-editor .ql-font-Courier-New {
font-family: "Courier New", monospace !important;
}
.ql-editor .ql-font-Verdana {
font-family: "Verdana", sans-serif !important;
}
.ql-editor .ql-font-Georgia {
font-family: "Georgia", serif !important;
}
.ql-editor .ql-font-Impact {
font-family: "Impact", sans-serif !important;
}
.ql-editor .ql-font-Comic-Sans-MS {
font-family: "Comic Sans MS", cursive !important;
}
.ql-editor .ql-font-sans-serif {
font-family: "sans-serif" !important;
}
.ql-editor .ql-font-serif {
font-family: "serif" !important;
}
.ql-editor .ql-font-monospace {
font-family: "monospace" !important;
}
/* 下拉菜单字体显示 */
.ql-snow .ql-picker.ql-font .ql-picker-label::before,
.ql-snow .ql-picker.ql-font .ql-picker-item::before {
content: '默认';
}
.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", serif;
}
.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", sans-serif;
}
.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: "Microsoft YaHei", sans-serif;
}
.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", serif;
}
.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", serif;
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="YouYuan"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="YouYuan"]::before {
content: '幼圆';
font-family: "YouYuan", sans-serif;
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="LiSu"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="LiSu"]::before {
content: '隶书';
font-family: "LiSu", serif;
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="STSong"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="STSong"]::before {
content: '宋体-繁';
font-family: "STSong", serif;
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="STZhongsong"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="STZhongsong"]::before {
content: '中宋-繁';
font-family: "STZhongsong", serif;
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="STKaiti"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="STKaiti"]::before {
content: '楷体-繁';
font-family: "STKaiti", serif;
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="STFangsong"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="STFangsong"]::before {
content: '仿宋-繁';
font-family: "STFangsong", serif;
}
.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", sans-serif;
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="Times-New-Roman"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="Times-New-Roman"]::before {
content: 'Times New Roman';
font-family: "Times New Roman", serif;
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="Courier-New"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="Courier-New"]::before {
content: 'Courier New';
font-family: "Courier New", monospace;
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="Verdana"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="Verdana"]::before {
content: 'Verdana';
font-family: "Verdana", sans-serif;
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="Georgia"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="Georgia"]::before {
content: 'Georgia';
font-family: "Georgia", serif;
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="Impact"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="Impact"]::before {
content: 'Impact';
font-family: "Impact", sans-serif;
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="Comic-Sans-MS"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="Comic-Sans-MS"]::before {
content: 'Comic Sans';
font-family: "Comic Sans MS", cursive;
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="sans-serif"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="sans-serif"]::before {
content: '无衬线';
font-family: "sans-serif";
}
.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: '衬线';
font-family: "serif";
}
.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: '等宽';
font-family: "monospace";
}
/* 字号样式 */
.ql-snow .ql-picker.ql-size .ql-picker-label::before,
.ql-snow .ql-picker.ql-size .ql-picker-item::before {
content: '16px';
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="8px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="8px"]::before {
content: '8px';
}
.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="18px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="18px"]::before {
content: '18px';
}
.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="22px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="22px"]::before {
content: '22px';
}
.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="26px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="26px"]::before {
content: '26px';
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="28px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="28px"]::before {
content: '28px';
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="30px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="30px"]::before {
content: '30px';
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="32px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="32px"]::before {
content: '32px';
}
.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-size .ql-picker-label[data-value="40px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="40px"]::before {
content: '40px';
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="48px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="48px"]::before {
content: '48px';
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="56px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="56px"]::before {
content: '56px';
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="64px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="64px"]::before {
content: '64px';
}
/* 编辑器内容字号样式 */
.ql-editor .ql-size-8px {
font-size: 8px !important;
}
.ql-editor .ql-size-10px {
font-size: 10px !important;
}
.ql-editor .ql-size-12px {
font-size: 12px !important;
}
.ql-editor .ql-size-14px {
font-size: 14px !important;
}
.ql-editor .ql-size-16px {
font-size: 16px !important;
}
.ql-editor .ql-size-18px {
font-size: 18px !important;
}
.ql-editor .ql-size-20px {
font-size: 20px !important;
}
.ql-editor .ql-size-22px {
font-size: 22px !important;
}
.ql-editor .ql-size-24px {
font-size: 24px !important;
}
.ql-editor .ql-size-26px {
font-size: 26px !important;
}
.ql-editor .ql-size-28px {
font-size: 28px !important;
}
.ql-editor .ql-size-30px {
font-size: 30px !important;
}
.ql-editor .ql-size-32px {
font-size: 32px !important;
}
.ql-editor .ql-size-36px {
font-size: 36px !important;
}
.ql-editor .ql-size-40px {
font-size: 40px !important;
}
.ql-editor .ql-size-48px {
font-size: 48px !important;
}
.ql-editor .ql-size-56px {
font-size: 56px !important;
}
.ql-editor .ql-size-64px {
font-size: 64px !important;
}
<
/style>
四、使用
// 使用
<quill-markdown v-model="articleForm.content" :height="600" :max-image-size="5"
:max-video-size="100" @image-uploaded="handleImageUploaded"
@video-uploaded="handleVideoUploaded">
<
/quill-markdown>
// 引入
import quillMarkdown from '../../components/quill-Markdown.vue'
// 注册
components: {
quillMarkdown
},
浙公网安备 33010602011771号