我们在开发后台管理系统的时候,通常会用到富文本,比如公告啦,新闻啦,各种图文详情啊等。其实vue能整合的富文本有很多,最好的应该是tinymce这款,但是这款在我们使用过程中,发现一个问题就是:同一个页面多个使用的时候,会有回显不正常的问题,图层错乱的问题,具体项目具体可能问题不一样。但是遇到了就记录在这里。所以我们之后就换了一个新的quill editor,感觉还不错,解决了上述问题:
当然了,得先初始化一个vue-cli3的项目,这里就不初始化了,不是重点。几乎是一搜一堆哦。
$ npm install quill --save
$ npm install vue-quill-editor --save
<template>
<div>
<el-upload
class='avatar-uploader'
:action='serverUrl'
name='file'
:headers='header'
: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 { quillEditor } from 'vue-quill-editor'
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'
// 工具栏配置
const toolbarOptions = [
['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', 'image', 'video']
]
export default {
props: {
/* 编辑器的内容 */
value: {
type: String
},
/* 图片大小 */
maxSize: {
type: Number,
default: 1024 * 5 // kb
}
},
components: {
quillEditor
},
data () {
return {
content: this.value,
quillUpdateImg: false, // 根据图片上传状态来确定是否显示loading动画,刚开始是false,不显示
editorOption: {
theme: 'snow', // or 'bubble'
placeholder: '请在这里输入...',
modules: {
toolbar: {
container: toolbarOptions,
handlers: {
// 处理图片上传
image: function (value) {
if (value) {
// 触发input框选择图片文件
document.querySelector('.avatar-uploader input').click()
} else {
this.quill.format('image', false)
}
}
}
}
}
},
serverUrl: `${window.SITE_CONFIG['apiURL']}/demo/upload/upload?type=1&token=${Cookies.get('token')}`, // 这里写你要上传的图片服务器地址
imageBaseUrl: `${window.SITE_CONFIG['imgBaseUrl']}`, // 这里写你要上传的图片服务器地址
header: {
// token: sessionStorage.token
} // 有的图片服务器要求请求头需要有token
}
},
methods: {
onEditorBlur () {
// 失去焦点事件
},
onEditorFocus () {
// 获得焦点事件
},
onEditorChange () {
// 内容改变事件
this.$emit('input', this.content)
},
// 富文本图片上传前
beforeUpload () {
// 显示loading动画
this.quillUpdateImg = true
},
uploadSuccess (res, file) {
// res为图片服务器返回的数据
// 获取富文本组件实例
let quill = this.$refs.myQuillEditor.quill
// 如果上传成功
if (res.code === 0) {
this.$message.success('图片上传成功')
// 获取光标所在位置
let length = quill.getSelection().index
// 插入图片 res.url为服务器返回的图片地址,需要拼接图片服务根地址
quill.insertEmbed(length, 'image', this.imageBaseUrl + res.data)
// 调整光标到最后
quill.setSelection(length + 1)
} else {
this.$message.warning('图片插入失败')
}
// loading动画消失
this.quillUpdateImg = false
},
// 富文本图片上传失败
uploadError () {
// loading动画消失
this.quillUpdateImg = false
this.$message.warning('图片插入失败')
}
}
}
script>
<style>
.editor {
line-height: normal !important;
height: 300px;
}
.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>
新建一个vue文件,引入quill-editor,然后就可以使用了,具体代码如下:
<template>
<div>
<div>
<div>QuillEditordiv>
{{content}}
<QuillEditor v-model="content">QuillEditor>
div>
<br>
<hr>
<br>
div>
template>
<script>
// 注意这边的路径,按照自己项目引入的实际路径引入即可
import QuillEditor from '../../components/quilleditor/quill-editor'
export default {
components: {
QuillEditor // 组件还是要写的,和import名保持一致。
},
data () {
return {
content: '' // 富文本绑定的参数
}
},
methods: {
}
}
script>