实现效果
1.版本
"vue-quill-editor": "^3.0.6",
2.组件使用
<template>
<div>
<div style="height:300px">
<quillEditorComponent v-model.trim="formData.context" :isReadOnly="isReadOnly" @getEditorContent="getEditorContent">
</quillEditorComponent>
</div>
</div>
</template>
<script>
import quillEditorComponent from '@/components/quillEditorComponent'
export default{
data () {
return{
formData: {
title: '',
kind: '',
context: '',
},
}
},
methods: {
getEditorContent (value) {
console.log(value, 'value')
this.$set(this.formData, 'context', value)
},
}
}
</script>
3.组件封装
<template>
<div>
<quill-editor ref="QuillEditor" class="editor" v-model.trim="content" :style="{height:height}" :options="editorOption" :disabled="isReadOnly" @blur="onEditorBlur($event)" @focus="onEditorFocus($event)" @ready="onEditorReady($event)" @change="onEditorChange($event)">
</quill-editor>
</div>
</template>
<script>
import { quillEditor } from 'vue-quill-editor'
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'
import * as Quill from "quill";
import { ImageDrop } from 'quill-image-drop-module'
import ImageResize from 'quill-image-resize-module'
import {ImageExtend} from 'quill-image-paste-module'
import {toolbarOptions, titleConfig, fontSize, fonts} from './data.js'
const Size = Quill.import('attributors/style/size')
Size.whitelist = fontSize
Quill.register(Size, true)
const Font = Quill.import('formats/font')
Font.whitelist = fonts
Quill.register(Font, true)
Quill.register('modules/imageDrop', ImageDrop)
Quill.register('modules/imageResize', ImageResize)
Quill.register('modules/ImageExtend', ImageExtend)
export default {
components: {quillEditor},
name: 'quillEditorComponent',
props: {
value: {
type: String,
default: {}
},
isReadOnly: {
type: Boolean,
default: false,
},
height: {
type: String,
default: '520px',
},
placeholder: {
type: String,
default: '请输入信息内容',
}
},
data () {
return {
content: '',
once: true,
editorOption: {
history: {
delay: 1000,
maxStack: 50,
userOnly: false
},
modules: {
toolbar: {
container: toolbarOptions,
},
// 拖拽上传
imageDrop: true,
// 调整图片大小
// imageResize: {
// displayStyles: {
// backgroundColor: 'black',
// border: 'none',
// color: 'white'
// },
// modules: [ 'Resize', 'DisplaySize', 'Toolbar' ]
// },
},
placeholder: this.placeholder,
},
}
},
watch: {
value (newVal) {
if (newVal) {
this.content = newVal
}
}
},
mounted () {
this.initTitle()
},
methods: {
initTitle () {
document.getElementsByClassName('ql-editor')[0].dataset.placeholder = ''
for (let item of titleConfig) {
let tip = document.querySelector('.quill-editor ' + item.Choice)
if (!tip) continue
tip.setAttribute('title', item.title)
}
},
// 失去焦点
onEditorBlur (editor) {
// console.log(editor, this.content, 'onEditorBlur');
this.$emit('getEditorContent', this.content)
},
// 获得焦点
onEditorFocus (editor) {
// console.log(editor, this.content, 'onEditorFocus');
},
// 开始
onEditorReady (editor) {
// console.log(editor,this.content, 'onEditorReady');
},
// 值发生变化
onEditorChange (editor) {
// 如果需要手动控制数据同步,父组件需要显式地处理changed事件
// this.content = editor.html;
// console.log(editor, 'onEditorChange');
this.$emit('getEditorContent', this.content)
},
}
}
</script>
<style>
@import './index.css';
</style>
4.样式文件 index.css
/* 字体风格 */
.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';
}
.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: 'Microsoft YaHei';
}
.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';
}
.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='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';
}
.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: 'sans-serif';
font-family: 'sans-serif';
}
.ql-font-SimSun {
font-family: 'SimSun';
}
.ql-font-SimHei {
font-family: 'SimHei';
}
.ql-font-Microsoft-YaHei {
font-family: 'Microsoft YaHei';
}
.ql-font-KaiTi {
font-family: 'KaiTi';
}
.ql-font-FangSong {
font-family: 'FangSong';
}
.ql-font-Arial {
font-family: 'Arial';
}
.ql-font-Times-New-Roman {
font-family: 'Times New Roman';
}
.ql-font-sans-serif {
font-family: 'sans-serif';
}
/* 字体大小 */
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="false"]::before{
content: 'Normal';
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="10px"]::before{
content: '10px';
}
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="10px"]::before {
content: '10px';
font-size: 10px;
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="14px"]::before{
content: '14px';
}
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="14px"]::before {
content: '14px';
font-size: 14px;
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="16px"]::before{
content: '16px';
}
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="16px"]::before {
content: '16px';
font-size: 16px;
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="18px"]::before {
content: '18px';
}
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="18px"]::before {
content: '18px';
font-size: 18px;
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="20px"]::before{
content: '20px';
}
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="20px"]::before {
content: '20px';
font-size: 20px;
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="24px"]::before{
content: '24px';
}
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="24px"]::before {
content: '24px';
font-size: 24px;
}
/* 段落大小 */
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before {
content: '标题1';
}
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before {
content: '标题2';
}
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before {
content: '标题3';
}
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before {
content: '标题4';
}
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before {
content: '标题5';
}
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="false"]::before {
content: '正常';
}
/* 默认设置 */
.ql-snow .ql-editor{
font-size: 14px;
}
/* 查看样式 */
.view-editor .ql-toolbar{
display: none;
}
.view-editor .ql-container.ql-snow{
border: 0;
}
.view-editor .ql-container.ql-snow .ql-editor{
padding: 0;
}
/* 编辑样式 */
.edit-editor .ql-toolbar{
display: block;
}
.edit-editor .ql-container.ql-snow{
border: 1px solid #ccc;
min-height: inherit;
}
5.配置文件 data.js
//toolbarOptions配置
export const toolbarOptions = [
['bold', 'italic', 'underline', 'strike'], // 加粗,倾斜,下划线,删除线
['blockquote', 'code-block'], // 引号,代码
[{ list: 'ordered' }, { list: 'bullet' }], // 有序列表,无序列表
[{ indent: '-1' }, { indent: '+1' }], // 左移,右移
[{ direction: 'rtl' }], // 左右对齐
[{ size: [false, '10px', '14px', '16px', '18px', '20px', '24px'] }], // 字体大小
[{ header: [1, 2, 3, 4, 5, false] }], // 标题大小
[{ color: [] }, { background: [] }], // 文字颜色,文字背景
[{ font: ['SimSun', 'SimHei', 'Microsoft-YaHei', 'KaiTi', 'FangSong', 'Arial', 'Times-New-Roman', 'sans-serif'] }], // 字体风格
[{ align: [] }], // 对齐方式
['image', 'video', 'link', 'clean']// 图片,链接,清除
]
// toolbar标题
export const titleConfig = [
{ Choice: '.ql-insertMetric', title: '跳转配置' },
{ Choice: '.ql-bold', title: '加粗' },
{ Choice: '.ql-italic', title: '斜体' },
{ Choice: '.ql-underline', title: '下划线' },
{ Choice: '.ql-header', title: '段落格式' },
{ Choice: '.ql-strike', title: '删除线' },
{ Choice: '.ql-blockquote', title: '块引用' },
{ Choice: '.ql-code', title: '插入代码' },
{ Choice: '.ql-code-block', title: '插入代码段' },
{ Choice: '.ql-font', title: '字体' },
{ Choice: '.ql-size', title: '字体大小' },
{ Choice: '.ql-list[value="ordered"]', title: '编号列表' },
{ Choice: '.ql-list[value="bullet"]', title: '项目列表' },
{ Choice: '.ql-direction', title: '文本方向' },
{ Choice: '.ql-header[value="1"]', title: 'h1' },
{ Choice: '.ql-header[value="2"]', title: 'h2' },
{ Choice: '.ql-align', title: '对齐方式' },
{ Choice: '.ql-color', title: '字体颜色' },
{ Choice: '.ql-background', title: '背景颜色' },
{ Choice: '.ql-image', title: '图像' },
{ Choice: '.ql-video', title: '视频' },
{ Choice: '.ql-link', title: '添加链接' },
{ Choice: '.ql-formula', title: '插入公式' },
{ Choice: '.ql-clean', title: '清除字体格式' },
{ Choice: '.ql-script[value="sub"]', title: '下标' },
{ Choice: '.ql-script[value="super"]', title: '上标' },
{ Choice: '.ql-indent[value="-1"]', title: '向左缩进' },
{ Choice: '.ql-indent[value="+1"]', title: '向右缩进' },
{ Choice: '.ql-header .ql-picker-label', title: '标题大小' },
{ Choice: '.ql-header .ql-picker-item[data-value="1"]', title: '标题一' },
{ Choice: '.ql-header .ql-picker-item[data-value="2"]', title: '标题二' },
{ Choice: '.ql-header .ql-picker-item[data-value="3"]', title: '标题三' },
{ Choice: '.ql-header .ql-picker-item[data-value="4"]', title: '标题四' },
{ Choice: '.ql-header .ql-picker-item[data-value="5"]', title: '标题五' },
{ Choice: '.ql-header .ql-picker-item[data-value="6"]', title: '标题六' },
{ Choice: '.ql-header .ql-picker-item:last-child', title: '标准' },
{ Choice: '.ql-size .ql-picker-item[data-value="small"]', title: '小号' },
{ Choice: '.ql-size .ql-picker-item[data-value="large"]', title: '大号' },
{ Choice: '.ql-size .ql-picker-item[data-value="huge"]', title: '超大号' },
{ Choice: '.ql-size .ql-picker-item:nth-child(2)', title: '标准' },
{ Choice: '.ql-align .ql-picker-item:first-child', title: '居左对齐' },
{ Choice: '.ql-align .ql-picker-item[data-value="center"]', title: '居中对齐' },
{ Choice: '.ql-align .ql-picker-item[data-value="right"]', title: '居右对齐' },
{ Choice: '.ql-align .ql-picker-item[data-value="justify"]', title: '两端对齐' }
]
export const fontSize = [false, '10px', '14px', '16px', '18px', '20px', '24px']
export const fonts = ['SimSun', 'SimHei', 'Microsoft-YaHei', 'KaiTi', 'FangSong', 'Arial', 'Times-New-Roman', 'sans-serif']