最近开发的一个vue3+element-plus的项目,需要用到富文本编辑器,最终选择了VueQuill这一款轻便型的富文本编辑器:官网地址为
https://vueup.github.io/vue-quill/guide/installation.html
首先,我们把它install下来,执行以下对应命令下载
npm install @vueup/vue-quill@beta --save# ORyarn add @vueup/vue-quill@beta
在vue项目的main.js中进行相关的配置
import {createApp } from 'vue'import {QuillEditor } from '@vueup/vue-quill'import '@vueup/vue-quill/dist/vue-quill.snow.css';const app = createApp()ponent('QuillEditor', QuillEditor)
我个人是将富文本编辑器封装成了公共组件,在components中创建editor.vue公共组件
引入quillEditor
import {QuillEditor } from '@vueup/vue-quill'import '@vueup/vue-quill/dist/vue-quill.snow.css';export default {components: {QuillEditor}}
在dom中使用
<template><QuillEditor theme="snow" /></template>
这样一个轻便的vue-quill富文本编辑器就出来了。然而,我们希望得到的数据是html的相关dom标签,希望图片不是以base64的格式保存到dom中,而是通过上传接口获得相应的超链接插入到我们需要的img标签里。这可咋办呢?别急,我们一一来对应。
首先quill输出的文件格式是需要配置的
<QuillEditorid="editorId"ref="myQuillEditor"//绑定数据需要加:content才能绑定成功v-model:content="content"theme="snow"//这里是指定富文本输出的文件,我需要的数据格式是html的,而默认是delta,这里小伙伴们需要特别注意contentType="html":options="options"/>
我们通过element的upload功能来实现上传图片的功能
<el-uploadclass="editor-img-uploader":action="upLoadUrl":show-file-list="false":headers="headers":on-success="handleAvatarSuccess":before-upload="beforeAvatarUpload"><i class="el-icon-plus editor-img-uploader"></i></el-upload>
并将此dom隐藏
<style scoped lang='less'>.editor-img-uploader {display: none;}.ql-editor {min-height: 300px;}</style>
在图片返回成功时通过获得富文本光标的位置动态将img标签插入我们希望它所在的位置
// 上传成功函数// 上传组件获得的图片地址反渲染近富文本中function handleSuccess(res) {// 获取富文本组件实例// 如果上传成功if (res) {// 获取富文本实例let quill = toRaw(myQuillEditor.value).getQuill()// 获取光标位置let length=quill.selection.savedRange.index;// 插入图片,res为服务器返回的图片链接地址quill.insertEmbed(length, "image", res);// 调整光标到最后quill.setSelection(length + 1);} else {// 提示信息,需引入MessageElMessage({message: "提交失败!",type: "error",});}}
完整代码如下
<template><div style="margin-bottom: 5px; border-radius: 10px"><el-uploadclass="editor-img-uploader":action="upLoadUrl":show-file-list="false":headers="headers":on-success="handleAvatarSuccess":before-upload="beforeAvatarUpload"><i class="el-icon-plus editor-img-uploader"></i></el-upload><QuillEditorid="editorId"ref="myQuillEditor"v-model:content="content"theme="snow"contentType="html":options="options"/></div></template><script>import {QuillEditor, Quill } from "@vueup/vue-quill";import {reactive, ref, toRaw } from "vue";import config from "../api/config";import {ElMessage } from "element-plus";import "@vueup/vue-quill/dist/vue-quill.snow.css";export default {components: {QuillEditor },props: {// 富文本编辑器getContent: {type: String, default: "" },},setup(props) {let content = ref("");content.value = props.getContent;let upLoadUrl = ref(config.baseUrl.product +"/api/uploadFileTwo?token=" +sessionStorage.getItem("token"));let headers = reactive({token: sessionStorage.getItem("token"),});const myQuillEditor=ref(null)const options = reactive({modules: {toolbar: {container: [[{size: ["small", false, "large"] }],["bold", "italic", "underline"],[{header: 1 }, {header: 2 }],[{list: "ordered" }, {list: "bullet" }],["link", "image"],[{color: [] }, {background: [] }],[{align: [] }]],handlers: {image: function (value) {if (value) {// 调用element图片上传document.querySelector(".editor-img-uploader>.el-upload").click();} else {Quill.format("image", true);}},},},history: {delay: 1000,maxStack: 50,userOnly: false},},});// 图片上传成功返回图片地址function handleAvatarSuccess(res, file) {// 如果上传成功if (res) {// 获取富文本实例let quill = toRaw(myQuillEditor.value).getQuill();// 获取光标位置let length = quill.selection.savedRange.index;// 插入图片,res为服务器返回的图片链接地址quill.insertEmbed(length, "image", res);// 调整光标到最后quill.setSelection(length + 1);} else {ElMessage({message: "提交失败!",type: "error",});}}// 图片上传前拦截function beforeAvatarUpload(file) {const type = ["image/jpeg", "image/jpg", "image/png", "image/svg"];const isJPG = type.includes(file.type);const isLt2M = file.size / 1024 / 1024 < 2;if (!isJPG) {ElMessage({message: "图片格式错误",type: "success",});}if (!isLt2M) {ElMessage({message: "上传图片不能超过" + size.value + "M",type: "success",});}return isJPG && isLt2M;}return {options,content,upLoadUrl,headers,myQuillEditor,handleAvatarSuccess,beforeAvatarUpload};},};</script><style scoped lang='less'>.editor-img-uploader {display: none;}.ql-editor {min-height: 300px;}</style>
我们如何去使用这个公共组件呢?
<editorComv-if="childDom"ref="editorRef":getContent="默认值"/>
要取的时候,我们通过ref来取this.$refs.editorRef.content即可获得值
content:this.$refs.editorRef.content
更新一版,vue3父子组件传值挺香的,之前没找到资料,做完项目来整理代码的时候才发现vue3里面拿值挺简单的,不过使用的地方挺多的,我已经不想动了,咳咳,后面优化项再来优化吧
// 初始化查询数据函数const init = async () => {const res = await companyInfoList({user_id: userInfo.value.user_id,id: sessionStorage.getItem("companyId")});form.value = res.data.response;childDom.value = true;};
好的,完整思路在这里了,话说,这才,我任务已经排满到是什么情况???(>﹏<。)~呜呜呜……