- 设置工具栏展示的工具选项
- 工具栏功能提示
- 事件重写,实现文件上传功能
- 事件重写,实现图片上传功能
- 实现图片拖拽上传
- 实现上传到富文本里的图片进行拖拽改变图片大小
- 父组件调用
一、富文本组件页面全部代码(QuillEditer.vue)
/**变量说明:
content:文本框中的内容。
quillConfig:全部相关配置
**/
<template>
<div class="edit_container">
<quill-editor
class="ql-editor"
v-model="content"
:id="id"
:ref="refs"
:options="quillOption"
@focus="onEditorFocus($event)"
@blur="onEditorBlur($event)"
@change="onEditorChange($event)"
></quill-editor>
</div>
</template>
<script>
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'
import { quillEditor } from 'vue-quill-editor'
import quillConfig from '@/utils/quillconfig.js'
import 'quill/dist/quill.min.js'
// 上传文件 插入a链接
import { Quill } from 'vue-quill-editor'
// 自定义插入a链接
var Link = Quill.import('formats/link')
class FileBlot extends Link {
// 继承Link Blot
static create(value) {
let node = undefined
if (value && !value.href) {
// 适应原本的Link Blot
node = super.create(value)
} else {
// 自定义Link Blot
node = super.create(value.href)
// node.setAttribute('download', value.innerText); // 左键点击即下载
node.innerText = value.innerText
node.download = value.innerText
}
return node
}
}
FileBlot.blotName = 'link'
FileBlot.tagName = 'A'
Quill.register(FileBlot)
// 上传文件 插入a链接over
export default {
name: 'VueQuillEditor',
components: {
quillEditor
},
props: ['id', 'refs', 'quillContent'],
data () {
return {
content: null, // 富文本内容
quillOption: quillConfig,//各配置项
}
},
created () {
this.content = this.quillContent
},
mounted() {
autotip:{
document.getElementsByClassName('ql-editor')[0].dataset.placeholder=''
for(let item of quillConfig.titleConfig){
let tip = document.querySelector('.quill-editor '+ item.Choice)
if (!tip) continue
tip.setAttribute('title',item.title)
}
}
},
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 }) {
this.content = html
this.$emit('childQuill',html)
},
}
}
</script>
<style scoped >
.ql-editor {
line-height: normal !important;
/* width: 335px; 我是需要展示给手机端所以设置了宽 */
}
.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>
<style>
/* 自定义上传文件的icon */
.ql-upload{
background-image: url("../assets/images/file.svg") !important;
background-size: 16px 16px !important;
background-position: center center !important;
background-repeat:no-repeat !important;
}
/* 隐藏文件上传的input type=file的样式 */
input.ql-upload {
height: 0 !important;
width: 0 !important;
padding: 0 !important;
}
</style>
二、富文本配置的全部代码(quillconfig.js)
import {
quillUploadimgAndfile
}
from "@/api/wenjuan"; //上传图片和文件的接口
//quill图片可拖拽上传
import { ImageDrop } from 'quill-image-drop-module';
Quill.register('modules/imageDrop', ImageDrop);
//quill图片可拖拽改变大小
import ImageResize from 'quill-image-resize-module'
Quill.register('modules/imageResize', ImageResize)
// toolbar工具栏的工具选项(默认展示全部)
const toolOptions = [
['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]}],
[{'color': []}, {'background': []}],
[{'font': []}],
[{'align': []}],
['clean'],
['link', 'image'],
['upload'],
];
const handlers = {
// 实现图片上传功能
image: function image() {
var self = this;
var fileInput = this.container.querySelector('input.ql-image[type=file]');
if (fileInput === null) {
fileInput = document.createElement('input');
fileInput.setAttribute('type', 'file');
// 设置图片参数名
fileInput.setAttribute('name', 'file');
// 可设置上传图片的格式
fileInput.setAttribute('accept','image/png, image/gif, image/jpeg, image/bmp, image/x-icon');
fileInput.classList.add('ql-image');
// 监听选择文件
fileInput.addEventListener('change', function () {
let formData = new FormData()
formData.append('file',fileInput.files[0])
quillUploadimgAndfile(formData).then(data => {//quillUploadimgAndfile是封装好的上传文件的方法
if (data.data.code === 1) {
let length = self.quill.getSelection(true).index;
self.quill.insertEmbed(length, 'image', data.data.data.url);
self.quill.insertEmbed(length, 'title', data.data.data.fileName);
self.quill.setSelection(length + 1)
}else {
this.$message.error(data.data.info)
}
}).catch(err => {
})
});
this.container.appendChild(fileInput);
}
fileInput.click();
},
// 实现文件上传功能
upload:function upload() {
var self = this;
var fileInput = self.container.querySelector('input.ql-upload[type=file]');
if (fileInput === null) {
fileInput = document.createElement('input');
fileInput.setAttribute('type', 'file');
// 设置图片参数名
fileInput.setAttribute('name', 'file');
// 限制上传文件的格式 具体限制格式类型见文章底部
// fileInput.setAttribute('accept','image/png, image/gif, image/jpeg, image/bmp, image/x-icon');
fileInput.classList.add('ql-upload');
// 监听选择文件
console.log('self.quill',self.quill)
fileInput.addEventListener('change', function () {
let formData = new FormData()
formData.append('file',fileInput.files[0])
quillUploadimgAndfile(formData).then(data => {//quillUploadimgAndfile是封装好的上传文件的方法
if (data.data.code === 1) {
console.log('asdasda',data.data.data)
let length = self.quill.getSelection(true).index;
// 插入文件,data为服务器返回的文件链接地址
//**注意这里 - 插入文件地址的方式**
self.quill.insertEmbed(length, 'link', {href: data.data.data.url, innerText: data.data.data.leName})
self.quill.setSelection(length + 1)
}else {
self.$message.error(data.data.info)
}
}).catch(err => {
})
});
this.container.appendChild(fileInput);
}
fileInput.click();
}
};
// 工具栏功能提示
const titleConfig=[
{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-upload',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 default {
placeholder: '',
theme: 'snow', // 主题
modules: {
toolbar: {
container: toolOptions, // 工具栏选项
handlers: handlers, // 事件重写
},
imageResize: {},// 拖拽改变图片大小
imageDrop:true, // 拖拽上传文件
},
titleConfig,
161 };
补充:上传文件限制类型:限制input type=“file“ 文件上传类型 - 躺在巨人肩膀上的小那 - 博客园
三、父组件页面调用富文本
<template>
<div>
<div class="container">
<QuillEditor ref="quillEditor" :quillContent="ruleForm.ext" @onEditorBlur="onEditorBlur" class="quillbox ql-editor"></QuillEditor>
<el-button type="primary" @click="submit" :loading="loading">保存</el-button>
</div>
</div>
</template>
<script>
import QuillEditor from '@/components/QuillEditor.vue'; // 富文本组件
export default {
components: {
QuillEditor, // 富文本组件
},
data() {
return {
ruleForm: {
ext: '', //富文本的内容
},
loading: false,
};
},
inject: ['reload'],
mounted() {
this.getPopdata();//获取默认数据
},
methods: {
getPopdata() {},
submit() {
this.loading = true;
this.$refs['ruleFormRef'].validate((valid) => {
if (valid) {
this.loading = false;//保存成功后loading置为false
}
});
},
// 富文本失去焦点事件
onEditorBlur(val) {
this.ruleForm.ext = val;
},
},
};
</script>
<style lang="scss" scoped>
</style>