第一步引用QuillEditor组件
import { QuillEditor, Quill } from '@vueup/vue-quill'
import ImageUploader from 'quill-image-uploader'
import '@vueup/vue-quill/dist/vue-quill.snow.css'
配置默认设置
const titleConfig = [
{ Choice: ' .ql-bold', title: '加粗' },
{ Choice: ' .ql-italic', title: '斜体' },
{ Choice: ' .ql-underline', title: '下划线' },
{ Choice: ' .ql-strike', title: '删除线' },
{ Choice: ' .ql-blockquote', title: '块引用' },
{ Choice: ' .ql-code-block', title: '插入代码' },
{ Choice: ' .ql-size', title: '字体大小' },
{ Choice: ' .ql-size', title: '字体大小' },
{ Choice: ' .ql-color', title: '字体颜色' },
{ Choice: ' .ql-background', title: '字体背景颜色' },
{ Choice: ' .ql-list[value="ordered"]', title: '有序列表' },
{ Choice: ' .ql-list[value="bullet"]', title: '无序列表' },
{ Choice: ' .ql-header[value="1"]', title: '1级标题' },
{ Choice: ' .ql-header[value="2"]', title: '2级标题' },
{ Choice: ' .ql-align', title: '对齐方式' },
{ Choice: ' .ql-clean', title: '清除字体格式' },
{ Choice: ' .ql-image', 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: '两端对齐' }
]
// 注册图片上传模块
Quill.register('modules/imageUploader', ImageUploader)
// Quill 编辑器选项
const editorOption = ref({
modules: {
// imageUploader: {
// upload: async file => {
// const localUrl = await getLocalImageURL(file)
// return localUrl // 返回本地图片的 URL 进行预览
// }
// },
toolbar: [
['bold', 'italic', 'underline', 'strike'], // 加粗,斜体,下划线,删除线
['blockquote', 'code-block'], // 引用,代码块
[{ header: 1 }, { header: 2 }], // 标题1,标题2
[{ list: 'ordered' }, { list: 'bullet' }], // 有序列表,无序列表
[{ size: ['small', false, 'large', 'huge'] }], // 文字大小
[{ color: [] }, { background: [] }], // 字体颜色,背景颜色
[{ align: [] }], // 对齐
['clean'], // 清除格式
['image'] // 链接,图片,视频
]
// ImageUploader: imageHandler
}
})
// 将 dataURL 转换为 File 对象的辅助函数
const dataURLtoFile = (dataurl, filename) => {
const arr = dataurl.split(',')
const mime = arr[0].match(/:(.*?);/)[1]
const bstr = atob(arr[1])
let n = bstr.length
const u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new File([u8arr], filename, { type: mime })
}
// 上传API
const uploadFileAPI = async file => {
const data = new FormData()
data.append('file', file)
return post('上传图片地址', data)
.then(({ data: { fullUrl } }) => {
return { data: { fullUrl } }
})
.catch(error => {
console.error('上传图片出错:', error)
throw error // 抛出错误以供外部处理
})
}
function initTitle() {
document.getElementsByClassName('ql-editor')[0].dataset.placeholder = ''
for (let item of titleConfig) {
let tip = document.querySelector('.ql-toolbar' + item.Choice)
if (!tip) continue
tip.setAttribute('title', item.title)
}
}
// 富文本设置
提交表单时需注意将富文本中的图片转为资源地址,不要使用原始的base64否则会导致数据库卡顿崩溃
<QuillEditor
v-model:content="state.modalForm.qillData"
ref="quillEditor"
:options="editorOption"
class="quill-editor"
/>
const quillEditor = ref(null) // 引用QuillEditor组件
// 提交表单
function submit() {
formRef.value.validate().then(async () => {
//获取富文本编辑器的内容
const deltaContent = quillEditor.value.getContents()
//获取图片
const imageUploadPromises = []
deltaContent.ops.forEach(op => {
if (op.insert && op.insert.image && op.insert.image.startsWith('data:')) {
const localSrc = op.insert.image
// 如果是 base64 图片,上传并替换为 URL
const file = dataURLtoFile(localSrc, 'image.png') // 将 base64 转换为 File 对象
const uploadPromise = uploadFileAPI(file).then(({ data: { fullUrl } }) => {
// 替换 op 中的 base64 URL 为服务器返回的 URL
op.insert.image = fullUrl
})
imageUploadPromises.push(uploadPromise)
}
})
try {
await Promise.all(imageUploadPromises)
//等所有图片上传并替换为资源地址之后进行下一步
...
} catch (error) {
state.fatherLoading = false
console.error('图片上传失败', error)
return // 终止提交
}
})
}
提交后的数据结构
{"ops":[{"insert":"哈哈哈哈\n"},{"insert":{"image":"http://10.40.0.63:9001/file-storage/485040200058040320.png"}},{"insert":"\n"},{"insert":{"image":"http://10.40.0.63:9001/file-storage/485040200647340032.png"}},{"insert":"\n啊睡大觉大胜靠德\n"}]}