<template>
<div>
<el-row>
<!-- myQuillEditor -->
<quill-editor v-model="content" class="qediter" ref="myQuillEditor" :options="editorOption" @change="onEditorChange($event)" @focus="onEditorFocus($event)" >
<!-- 自定义toolar -->
<div :id="id" slot="toolbar" style="line-height: 24px;">
<!-- Add a bold button -->
<button class="ql-bold" title="加粗">Bold</button>
<button class="ql-italic" title="斜体">Italic</button>
<button class="ql-underline" title="下划线">underline</button>
<button class="ql-strike" title="删除线">strike</button>
<button class="ql-blockquote" title="引用"></button>
<button class="ql-code-block" title="代码"></button>
<button class="ql-header" value="1" title="标题1"></button>
<button class="ql-header" value="2" title="标题2"></button>
<!--Add list -->
<button class="ql-list" value="ordered" title="有序列表"></button>
<button class="ql-list" value="bullet" title="无序列表"></button>
<!-- Add font size dropdown -->
<select class="ql-header" title="段落格式">
<option selected>段落</option>
<option value="1">标题1</option>
<option value="2">标题2</option>
<option value="3">标题3</option>
<option value="4">标题4</option>
<option value="5">标题5</option>
<option value="6">标题6</option>
</select>
<select class="ql-size" title="字体大小">
<option value="10px">10px</option>
<option value="12px">12px</option>
<option value="14px">14px</option>
<option value="16px" selected>16px</option>
<option value="18px">18px</option>
<option value="20px">20px</option>
</select>
<select class="ql-font" title="字体">
<option value="SimSun">宋体</option>
<option value="SimHei">黑体</option>
<option value="Microsoft-YaHei">微软雅黑</option>
<option value="KaiTi">楷体</option>
<option value="FangSong">仿宋</option>
<option value="Arial">Arial</option>
</select>
<!-- Add subscript and superscript buttons -->
<select class="ql-color" value="color" title="字体颜色"></select>
<select class="ql-background" value="background" title="背景颜色"></select>
<select class="ql-align" value="align" title="对齐"></select>
<button class="ql-clean" title="还原"></button>
<!-- You can also add your own -->
<button class="ql-link" title="超链接"></button>
<button class="ql-image" title="照片"></button>
<button class="ql-video" title="视频"></button>
<el-upload
class="avatar-uploader"
action="/api/VisionAward/imgUpload"
:headers="myHeaders"
name="file"
:on-error="picError"
accept="image/*"
:on-success="uploadSuccess"
:before-upload="picBeforeupload"
:show-file-list="false"
>
<slot name="trigger">
<div id="editorUploadImage" />
</slot>
</el-upload>
</div>
</quill-editor>
<div style="text-align:right;color:#999;">
{{TiLength}}/{{lengths}}</div>
</el-row>
</div>
</template>
<script>
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'
import { Quill,quillEditor } from 'vue-quill-editor'
import {container, ImageExtend} from 'quill-image-extend-module'
Quill.register('modules/ImageExtend', ImageExtend)
// 自定义字体大小
let Size = Quill.import('attributors/style/size')
Size.whitelist = ['10px', '12px', '14px', '16px', '18px', '20px']
Quill.register(Size, true)
// 自定义字体类型
var fonts = ['SimSun', 'SimHei', 'Microsoft-YaHei', 'KaiTi', 'FangSong', 'Arial', 'Times-New-Roman', 'sans-serif',
'宋体', '黑体'
]
var Font = Quill.import('formats/font')
Font.whitelist = fonts
Quill.register(Font, true)
export default {
name: "ueditor",
components: {
quillEditor
},
props:{
id: {
type: String|Number,
default: 'editor1',
},
/*编辑器的内容*/
value: {
type: String,
default: '',
},
option: {
type: Object,
default: () => ({}),
},
height: {
type: Number,
default: 200,
},
isfill: {
type: Number|String,
default: 1,
},
lengths:{
type: Number|String,
default: 10000,
}
},
data(){
let _this = this;
return{
content: this.value,
addImgRange: null,
TiLength:0,
myHeaders: {access_token: this.$store.state.access_token},//上传头部
serverUrl: '/api/User/uploadImages', // 这里写你要上传的图片服务器地址
editorOption: { // 富文本编辑器配置
theme: 'snow',
placeholder: '请输入正文',
modules: {
ImageExtend: {
loading: true,
name: 'file',
size: 5, // 单位为M, 1M = 1024KB
action: this.serverUrl,
headers: (xhr) => {
xhr.setRequestHeader('access_token', this.$store.state.access_token)
},
response: (res) => {
return res.data
}
},
toolbar: {
container: '#'+_this.id,
handlers: {
'image': function (value) {
if (value) {
document.querySelector('#'+_this.id+' .avatar-uploader .el-upload .el-upload__input').click()
} else {
this.quill.format('image', false);
}
}
}
}
}
},
}
},
watch: {
value: {
handler(newValue, preValue) {
if (newValue !== preValue && newValue !== this.content) {
this.content = newValue
}
},
immediate: true,
},
},
created() {
Object.assign(this.editorOption, this.option)
},
mounted() {
this.init()
},
beforeDestroy(){
this.$refs.myQuillEditor.quill = null;
delete this.$refs.myQuillEditor.quill;
},
computed: {
editor() {
return this.$refs.myQuillEditor.quill;
}
},
methods:{
init() {
// 重写图片添加图片
const imgHandler = state => {
if (state) {
document.getElementById('editorUploadImage').click()
}
}
this.$refs.myQuillEditor.quill.getModule('toolbar').addHandler('ql-image', imgHandler)
},
// 图片大小检查
picBeforeupload(file) {
const isLt4M = file.size / 1024 / 1024 < 5
if (!isLt4M) {
this.$message.error('上传图片大小不能超过 5MB!')
}
return isLt4M
},
// 上传图片
async picUpload(item) {
try {
const formData = new FormData()
formData.append('file', item.file)
const res = await uploadArticleImgApi(formData)
this.addImg(res.data.url)
} catch (e) {
item.onError()
}
},
// 上传图片失败
picError() {
this.$message({
message: '图片添加失败,请重试',
type: 'error',
})
},
// 添加图片
addImg(imgUrl) {
this.addImgRange = this.$refs.myQuillEditor.quill.getSelection() // 检索用户的选择范围, 如果编辑没有焦点,可能会返回一个null
this.$refs.myQuillEditor.quill.insertEmbed(
this.addImgRange != null ? this.addImgRange.index : 0,
'image',
imgUrl,
Quill.sources.USER,
)
},
uploadSuccess(res,file) { //把已经上传的图片显示回富文本编辑框中
// res为图片服务器返回的数据
// 获取富文本组件实例
let quill = this.$refs.myQuillEditor.quill
// 如果上传成功
if (res.code == 1 ) {
// 获取光标所在位置
let length = quill.getSelection().index;
// 插入图片 res.url为服务器返回的图片地址
quill.insertEmbed(length, 'image', res.data.url)
// 调整光标到最后
quill.setSelection(length + 1)
} else {
this.$message.error('图片插入失败')
}
},
onEditorFocus(event) {
if(this.isfill == 0){
event.enable(false);
}
},
// onEditorFocus(editor){
// //获得焦点事件
// console.log("获得焦点");
// var selection = getSelection();
// //设置最后光标对象
// this.lastEditRange = selection.getRangeAt(0);
//
// console.log(this.lastEditRange);
//
// },
// // 富文本编辑器 内容改变事件
onEditorChange(event) {//内容改变事件
event.quill.deleteText(this.lengths,1);
if(this.content===0){
this.TiLength = 0
}
else{
this.TiLength = event.quill.getLength()-1
}
this.content = event.html
this.$emit("input", this.content);
},
}
}
</script>
<style scoped>
.avatar-uploader{
display: none;
}
.ql-toolbar.ql-snow{
padding:unset;
}
.quill-editor>>> .ql-toolbar.ql-snow + .ql-container.ql-snow{
height:200px;
}
</style>
以上代码可直接复制使用↑↑↑↑
安装 npm install quill-editor --save
注意这一段必须要引入动态ID否则多个编辑器中 上传图片只有第一个有效:
toolbar: {
container: '#'+_this.id,
handlers: {
'image': function (value) {
if (value) {//动态的ID
document.querySelector('#'+_this.id+' .avatar-uploader .el-upload .el-upload__input').click()
} else {
this.quill.format('image', false);
}
}
}
}
element 上传组件必须放在自定义toobar的 动态ID中
引用: 绑定不同的ID
<qeditor id="editor23" :content="内容" v-model="model" :height="400"></qeditor>