安装
npm install vue-quill-editor --save
引入
全局引用
// main.js
import VueQuillEditor from 'vue-quill-editor'
// require styles
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'
Vue.use(VueQuillEditor)
封装组件
import Cookies from 'vue-cookies' // cookies用于存放token
import apis from '../http/apis/common/index' // 引入存放上传图片接口的路径
let base = process.env.VUE_APP_BASE_URL + process.env.VUE_APP_MAPPING // 域名
let url = base + apis.upload.url // 上传图片接口
/* 富文本编辑图片上传配置 */
const uploadConfig = {
action: url, // 必填参数 图片上传地址
methods: 'POST', // 必填参数 图片上传方式
token: Cookies.get('token'), // 可选参数 如果需要token验证,假设你的token有存放在sessionStorage
name: 'file', // 必填参数 文件的参数名
size: 500, // 可选参数 图片大小,单位为Kb, 1M = 1024Kb
accept: 'image/png, image/gif, image/jpeg, image/bmp, image/x-icon' // 可选 可上传的图片格式
}
// 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', 'video'],
// 自己添加编辑源码方法
['sourceEditor']
// ['image']
]
const handlers = {
shadeBox: null,
// 添加编辑源码方法
sourceEditor: function() {
const container = this.container;
const firstChild = container.nextElementSibling.firstChild;
// 在第一次点击源码编辑的时候,会在整个工具条上加一个div,层级比工具条高,再次点击工具条任意位置,就会退出源码编辑。可以在下面cssText里面加个背景颜色看看效果。
if (!this.shadeBox) {
let shadeBox = this.shadeBox = document.createElement('div')
shadeBox.style.cssText = 'position:absolute; top:0; left:0; width:100%; height:100%; cursor:pointer;'
container.style.position = 'relative'
container.appendChild(shadeBox)
firstChild.innerText = firstChild.innerHTML
shadeBox.addEventListener('click', function() {
this.style.display = 'none'
firstChild.innerHTML = firstChild.innerText.trim()
}, false)
} else {
this.shadeBox.style.display = 'block'
firstChild.innerText = firstChild.innerHTML
}
},
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')
// 设置图片参数名
if (uploadConfig.name) {
fileInput.setAttribute('name', uploadConfig.name)
}
// 可设置上传图片的格式
fileInput.setAttribute('accept', uploadConfig.accept)
fileInput.classList.add('ql-image')
// 监听选择文件
fileInput.addEventListener('change', function() {
// 创建formData
var formData = new FormData()
formData.append(uploadConfig.name, fileInput.files[0])
formData.append('object', 'product')
// 如果需要token且存在token
if (uploadConfig.token) {
formData.append('token', uploadConfig.token)
}
// 图片上传
var xhr = new XMLHttpRequest()
xhr.open(uploadConfig.methods, uploadConfig.action, true)
// 上传数据成功,会触发
xhr.onload = function(e) {
if (xhr.status === 200) {
var res = JSON.parse(xhr.responseText)
let length = self.quill.getSelection(true).index
// 这里很重要,你图片上传成功后,img的src需要在这里添加,res.data.path就是你服务器返回的图片链接。
self.quill.insertEmbed(length, 'image', res.data.path)
self.quill.setSelection(length + 1)
}
fileInput.value = ''
}
// 开始上传数据
xhr.upload.onloadstart = function(e) {
fileInput.value = ''
}
// 当发生网络异常的时候会触发,如果上传数据的过程还未结束
xhr.upload.onerror = function(e) {
}
// 上传数据完成(成功或者失败)时会触发
xhr.upload.onloadend = function(e) {
// console.log('上传结束')
}
xhr.send(formData)
})
this.container.appendChild(fileInput)
}
fileInput.click()
}
}
export default {
placeholder: '请输入内容',
theme: 'snow', // 主题
modules: {
toolbar: {
container: toolOptions, // 工具栏选项
handlers: handlers // 事件重写
}
}
}
使用组件
<template>
<div>
<quill-editor class="quill-editor" v-model="editorInfo" :options="option">
</quill-editor>
</div>
</template>
<script>
// script
import quillConfig from '@/utils/quill-config'
data(){
return {
option:quillConfig,
}
}
// 根据后端需求要求转换editor
// 传参时:encodeURI(editorInfo)
// 接受参数时:decodeURI(res.data.editorInfo)
</script>
<style lang="scss">
// editor 源码编辑按钮
.ql-sourceEditor {
background: url("https://i.loli.net/2021/03/25/MC5puJHoaxjTbBz.jpg") no-repeat !important;
background-size: contain !important;
width: 18px !important;
height: 18px !important;
}
</style>
局部使用
<template>
<div>
<quill-editor ref="myTextEditor" v-model="editorInfo" :options="editorOption" style="height:500px;"></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'
export default {
data(){
return{
editorInfo: '',
editorOption: {
placeholder: '编辑文章内容'
}
}
},
components: {
quillEditor
},
methods:{
onEditorChange({ editor, html, text }) {
this.editorInfo= html
}
}
}
</script>
网友评论