直接上代码
<template>
<div class="edit">
<quill-editor
v-model="content"
ref="myQuillEditor"
:options="editorOption"
@focus="onEditorFocus($event)"
@blur="onEditorBlur($event)"
@change="onEditorChange($event)"
>
<!-- 自定义工具栏-start -->
<div id="toolbar" slot="toolbar">
<button class="ql-bold" title="加粗">Bold</button>
<select class="ql-header" title="段落格式">
<option selected>正文</option>
<option value="2">标题1</option>
<option value="3">标题2</option>
<option value="4">标题3</option>
</select>
<button class="ql-list" value="ordered" title="有序列表"></button>
<button class="ql-list" value="bullet" title="无序列表"></button>
<button class="ql-align" value="" title="左对齐"></button>
<button class="ql-align" value="center" title="中间对齐"></button>
<button class="ql-align" value="right" title="右对齐"></button>
<select class="ql-color" value="color" title="字体颜色"></select>
<!-- 插入图片 -->
<span class="el-icon-picture icon-pic custom-icon" title="图片" @click="insertImgClick($event)"></span>
<!-- 插入视频 -->
<!-- <span class="el-icon-video-camera icon-video custom-icon" title="视频" @click="insertImgClick($event)"></span> -->
<!-- 选择图片input -->
<input style="display: none;" type="file" id="insert_image" @change="fileInsert($event)" />
<!-- 选择视频input -->
<!-- <input style="display: none;" type="file" id="insert_video" @change="fileInsert($event)" /> -->
</div>
<!-- 自定义工具栏-end -->
</quill-editor>
<!-- 预览 -->
<!-- <div class="output ql-snow">
<div class="title">Output</div>
<div class="ql-editor" v-html="content"></div>
</div> -->
</div>
</template>
<script>
import httpUpload from '../axios/clockIn/index'
import { quillEditor } from 'vue-quill-editor' // 调用富文本编辑器
import 'quill/dist/quill.snow.css' // 富文本编辑器外部引用样式 三种样式三选一引入即可
// import 'quill/dist/quill.core.css'
// import 'quill/dist/quill.bubble.css'
import * as Quill from 'quill' // 富文本基于quill
const toolbarList = [
['bold', 'italic', 'underline', 'strike'],
['blockquote', 'code-block'],
[{ header: 1 }, { header: 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] }],
[{ font: [] }],
[{ color: [] }, { background: [] }],
[{ align: [] }],
['clean'],
['link', 'image', 'video']
]
export default {
components: {
quillEditor
},
data() {
return {
editor: null, // 富文本编辑器对象
content: ``, // 富文本编辑器默认内容
editorOption: {
// 富文本编辑器配置
modules: {
toolbar: '#toolbar'
// toolbar: toolbarList
},
theme: 'snow',
placeholder: '请输入正文'
}
}
},
mounted() {
this.editor = this.$refs.myQuillEditor.quill
},
beforeDestroy() {
this.editor = null
delete this.editor
},
methods: {
// 准备富文本编辑器
onEditorReady(editor) {},
// 富文本编辑器 失去焦点事件
onEditorBlur(editor) {},
// 富文本编辑器 获得焦点事件
onEditorFocus(editor) {},
// 富文本编辑器 内容改变事件
onEditorChange(editor) {
// console.log(editor)
},
// 富文本编辑器 点击插入图片或者视频
insertImgClick(e) {
if (e.target.className.indexOf('icon-pic') != -1) {
document.getElementById('insert_image').click()
} else if (e.target.className.indexOf('icon-video') != -1) {
document.getElementById('insert_video').click()
}
},
// 富文本编辑器 点击插入图片或者视频上传并预览
fileInsert(e) {
var oFile = e.target.files[0]
if (typeof oFile === 'undefined') {
return
}
let sExtensionName = oFile.name.substring(oFile.name.lastIndexOf('.') + 1).toLowerCase() // 文件扩展名
let sfileType = '' // 上传文件类型
if (e.target.id == 'insert_image') {
sfileType = 'image'
if (sExtensionName !== 'png' && sExtensionName !== 'jpg' && sExtensionName !== 'jpeg') {
alert('不支持该类型图片')
return
}
}
if (e.target.id == 'insert_video') {
sfileType = 'video'
if (sExtensionName !== 'mp4' && sExtensionName !== 'avi' && sExtensionName !== 'mov') {
alert('不支持该类型视频')
return
}
let maxSize = 100 * 1024 * 1024 // 100MB
if (oFile.size > maxSize) {
alert('上传视频大小不能超过100MB')
return
}
}
var reader = new FileReader()
reader.readAsDataURL(oFile)
reader.onloadend = () => {
let formData = new FormData() // 通过formdata上传
formData.append('file', oFile)
httpUpload
.uploadFile(formData)
.then(res => {
console.log(res)
this.editor.insertEmbed(this.editor.selection.savedRange.index, sfileType, res.data.url) // 这个方法用来手动插入dom到编辑器里
/* let isAndroid = this.$is_android() // 判断是ios还是android
if (isAndroid) {
$('video').removeAttr('controls')
$('video').attr('x5-video-player-type', 'h5')
} */
this.editor.setSelection(this.editor.selection.savedRange.index + 1) // 这个方法可以获取光标位置
})
.catch(response => {
console.error('富文本编辑器上传图片失败', response)
})
}
}
}
}
</script>
<style lang="less" scoped>
.edit {
/deep/ .ql-editor {
min-height: 400px;
}
.custom-icon {
font-size: 18px;
line-height: 22px;
padding: 0 5px;
}
.output {
border: 1px solid #ccc;
border-left: none;
.title {
height: 40px;
line-height: 40px;
border-bottom: 1px solid #ccc;
}
}
}
</style>
/** 开发笔记: 参考: 简书:https://www.jianshu.com/p/1675bcd396a2 github:https://github.com/surmon-china/vue-quill-editor */
//http.js
/**
* 上传文件-富文本编辑器处使用
*/
uploadFile(params) {
return axios.post('file/upload', params, {
headers: { 'Content-Type': 'multipart/form-data' }
})
},
注意
当在其它端(小程序等)单独显示富文本内容的时候,别忘了了引入"quill.snow.css"样式