vue-quill-editor 相关使用
前言:如何实现嵌入富文本编辑器,让用户编写文章的需求 ?在 VUE 项目中,选择使用轻量化的 vue-quill-editor 插件 去完成实现 。这里主要对其使用过程,样式优化做一个总结 。
项目中安装依赖 (推荐使用 cnpm ,淘宝镜像)
npm i --save vue-quill-editor
// 或者
cnpm i --save vue-quill-editor
组件中引入插件 (局部引入,注册)
// 引入 vue-quill-edito 组件
import { quillEditor } from 'vue-quill-editor'
// 引入组件相关样式文件
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'
...
// 组件注册
components: {
quillEditor
}
组件中基础使用
<!-- 基础使用 -->
<template>
<div>
<quill-editor
v-model="content"
:options="editorOption"
@blur="onEditorBlur($event)"
@focus="onEditorFocus($event)"
@ready="onEditorReady($event)"
@change="onEditorChange($event)"
class="editor"
/>
</div>
</template>
<script>
// 引入 vue-quill-edito 组件
import { quillEditor } from 'vue-quill-editor'
// 引入组件相关样式文件
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'
export default {
name: 'Test',
// 组件注册
components: {
quillEditor
},
data() {
return {
// 富文本编辑器默认内容
content: '',
// 富文本编辑器配置
editorOption: {}
}
},
methods: {
// 失去焦点事件
onEditorBlur(quill) {
console.log('editor blur!', quill)
},
// 获得焦点事件
onEditorFocus(quill) {
console.log('editor focus!', quill)
},
// 准备富文本编辑器
onEditorReady(quill) {
console.log('editor ready!', quill)
},
// 内容改变事件
onEditorChange({ quill, html, text }) {
console.log('editor change!', quill, html, text)
this.content = html
}
}
}
</script>
<style lang="css" scoped>
.editor {
width: 1200px;
height: 500px;
margin: 20px auto;
}
</style>
工具栏配置对象
- 工具栏配置对象(注释,可以控制工具栏功能控件的有无)
// 工具栏配置
const toolbarOptions = [
// [加粗,斜体,下划线,删除线]
['bold', 'italic', 'underline', 'strike'],
// [引用,代码块]
['blockquote', 'code-block'],
// [1 级标题,2 级标题]
[{ header: 1 }, { header: 2 }],
// [有序列表,无序列表]
[{ list: 'ordered' }, { list: 'bullet' }],
// [上标,下标]
[{ script: 'sub' }, { script: 'super' }],
// [左缩进,右缩进]
[{ indent: '-1' }, { indent: '+1' }],
// [文本方向]
[{ direction: 'rtl' }],
// [字体大小]
[{ size: ['small', false, 'large', 'huge'] }],
// [1-6 级标题]
[{ header: [1, 2, 3, 4, 5, 6, false] }],
// [字体颜色,字体背景颜色]
[{ color: [] }, { background: [] }],
// [字体种类]
[{ font: [] }],
// [对齐方式]
[{ align: [] }],
// [清除文本格式]
['clean'],
// [链接,图片,视频]
['link', 'image', 'video']
]
- data 中的 editorOption 写法变更
//富文本编辑器配置
editorOption: {
modules: {
//工具栏定义的
toolbar: toolbarOptions
},
//主题
theme: 'snow',
placeholder: '请输入正文'
}
更改中文工具栏显示(拷贝下面代码到组件 style 中,或外部新建文件引入)
.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';
}
.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='serif']::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value='serif']::before {
content: '衬线字体';
}
.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: '等宽字体';
}
工具栏添加鼠标悬浮中文提示
- titleConfig,js 文件(外部新建标题配置文件)
const titleConfig = {
'ql-bold': '加粗',
'ql-color': '颜色',
'ql-font': '字体',
'ql-code': '插入代码',
'ql-italic': '斜体',
'ql-link': '添加链接',
'ql-background': '背景颜色',
'ql-size': '字体大小',
'ql-strike': '删除线',
'ql-script': '上标/下标',
'ql-underline': '下划线',
'ql-blockquote': '引用',
'ql-header': '标题',
'ql-indent': '缩进',
'ql-list': '列表',
'ql-align': '文本对齐',
'ql-direction': '文本方向',
'ql-code-block': '代码块',
'ql-formula': '公式',
'ql-image': '图片',
'ql-video': '视频',
'ql-clean': '清除字体样式'
};
export function addQuillTitle() {
const oToolBar = document.querySelector('.ql-toolbar'),
aButton = oToolBar.querySelectorAll('button'),
aSelect = oToolBar.querySelectorAll('select');
aButton.forEach(function (item) {
if (item.className === 'ql-script') {
item.value === 'sub' ? item.title = '下标' : item.title = '上标'
} else if (item.className === 'ql-indent') {
item.value === '+1' ? item.title = '向右缩进' : item.title = '向左缩进'
} else {
item.title = titleConfig[item.classList[0]]
}
});
aSelect.forEach(function (item) {
item.parentNode.title = titleConfig[item.classList[0]]
})
}
- 组件中引入,mounted 中触发相关函数
import { addQuillTitle } from '../assets/js/title'
......
mounted() {
this.$nextTick(() => {
// 富文本提示信息
addQuillTitle()
})
}
完整示例组件
<!-- 工具栏汉化,添加悬浮提示 -->
<template>
<div>
<quill-editor
v-model="content"
:options="editorOption"
@blur="onEditorBlur($event)"
@focus="onEditorFocus($event)"
@ready="onEditorReady($event)"
@change="onEditorChange($event)"
class="editor"
/>
</div>
</template>
<script>
// 引入 vue-quill-edito 组件
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 { addQuillTitle } from '../assets/js/title'
// 工具栏配置
const toolbarOptions = [
// [加粗,斜体,下划线,删除线]
['bold', 'italic', 'underline', 'strike'],
// [引用,代码块]
['blockquote', 'code-block'],
// [1 级标题,2 级标题]
[{ header: 1 }, { header: 2 }],
// [有序列表,无序列表]
[{ list: 'ordered' }, { list: 'bullet' }],
// [上标,下标]
[{ script: 'sub' }, { script: 'super' }],
// [左缩进,右缩进]
[{ indent: '-1' }, { indent: '+1' }],
// [文本方向]
[{ direction: 'rtl' }],
// [字体大小]
[{ size: ['small', false, 'large', 'huge'] }],
// [1-6 级标题]
[{ header: [1, 2, 3, 4, 5, 6, false] }],
// [字体颜色,字体背景颜色]
[{ color: [] }, { background: [] }],
// [字体种类]
[{ font: [] }],
// [对齐方式]
[{ align: [] }],
// [清除文本格式]
['clean'],
// [链接,图片,视频]
['link', 'image', 'video']
]
export default {
name: 'Test',
// 组件注册
components: {
quillEditor
},
data() {
return {
// 富文本编辑器默认内容
content: '',
// 富文本编辑器配置
editorOption: {
modules: {
// 工具栏定义
toolbar: toolbarOptions
},
// 主题
theme: 'snow',
placeholder: '请输入正文'
}
}
},
mounted() {
this.$nextTick(() => {
// 富文本提示信息
addQuillTitle()
})
},
methods: {
// 失去焦点事件
onEditorBlur(quill) {
console.log('editor blur!', quill)
},
// 获得焦点事件
onEditorFocus(quill) {
console.log('editor focus!', quill)
},
// 准备富文本编辑器
onEditorReady(quill) {
console.log('editor ready!', quill)
},
// 内容改变事件
onEditorChange({ quill, html, text }) {
console.log('editor change!', quill, html, text)
this.content = html
}
}
}
</script>
<style lang="css">
.editor {
line-height: normal !important;
width: 1200px;
height: 500px;
margin: 20px auto;
}
.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';
}
.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='serif']::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value='serif']::before {
content: '衬线字体';
}
.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: '等宽字体';
}
</style>