vue富文本 vue-quill-editor + 上传图片到阿里云服务器 + 修改富文本内容
前言
使用富文本编辑器,需要将图片上传到服务器,完成之后,还需要在修改页面完成修改富文本内容,使用的富文本插件是vue-quill-editor,

一 、安装 vue-quill-editor
npm i vue-quill-editor
npm install quill --save
npm install quill-image-resize-module --save // 图片缩放组件引用
npm i quill-image-drop-module -S // 图片拖动组件引用
npm install axios // 上传阿里云服务器用
二、引入
import 'quill/dist/quill.core.css';
import 'quill/dist/quill.snow.css';
import 'quill/dist/quill.bubble.css';
import { quillEditor, Quill } from 'vue-quill-editor';
import axios from 'axios';// 如果要图片拖拽功能,增加这两个插件
import { ImageDrop } from "quill-image-drop-module"; // 图片拖动组件引用
import ImageResize from "quill-image-resize-module"; // 图片缩放组件引用
Quill.register("modules/imageDrop", ImageDrop); // 注册
Quill.register("modules/imageResize", ImageResize); // 注册
三、配置 vue.config
const { defineConfig } = require('@vue/cli-service')
const webpack = require('webpack') // 引入webpack
module.exports = defineConfig({configureWebpack: {plugins: [new webpack.ProvidePlugin({'window.Quill': 'quill/dist/quill.js','Quill': 'quill/dist/quill.js'})]},
})
四 、上传图片到阿里云成功后的图片显示预览

五、富文本组件代码
<template><div class="editor"><quill-editor class="ql-editor" v-model="content" ref="myQuillEditor" :options="editorOption"@blur="onEditorBlur($event)" @focus="onEditorFocus($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, Quill } from 'vue-quill-editor';
import axios from 'axios';// 如果要图片拖拽功能,增加这两个插件
import { ImageDrop } from "quill-image-drop-module"; // 图片拖动组件引用
import ImageResize from "quill-image-resize-module"; // 图片缩放组件引用
Quill.register("modules/imageDrop", ImageDrop); // 注册
Quill.register("modules/imageResize", ImageResize); // 注册export default {name: "customEditor",components: {quillEditor},props: {value: {type: String,default: ''}},watch: {value(newValue) {this.content = newValue; // 监听 props.value 的变化},content(newValue) {this.$emit('content-changed', newValue); // 向父组件发出事件}},data() {return {content: this.value,editorOption: {modules: {toolbar: [["bold", "italic", "underline", "strike"], //加粗,斜体,下划线,删除线["blockquote", "code-block"], //引用,代码块[{ header: 1 }, { header: 2 }], // 标题,键值对的形式;1、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"], //清除字体样式["image",], //上传图片、上传视频 "video"]},imageDrop: true,imageResize: {displayStyles: {backgroundColor: 'black',border: 'none',color: 'white'},modules: ['Resize', 'DisplaySize', 'Toolbar']}},};},mounted() {// 获取工具栏实例并覆盖图片处理函数const toolbar = this.$refs.myQuillEditor.quill.getModule('toolbar');toolbar.addHandler('image', this.handleImageUpload);},methods: {// 处理图片上传事件handleImageUpload() {const input = document.createElement('input');input.setAttribute('type', 'file');input.setAttribute('accept', 'image/*');input.onchange = async () => {const file = input.files[0];if (file) {await this.uploadImage(file);}};input.click();},// 上传图片到阿里云服务器async uploadImage(file) {// console.log("file", file);try {// 获取阿里云上传凭证const res = await this.$axios("feiyong/ossNews")// console.log("res", JSON.parse(JSON.stringify(res)));const formData = new FormData();const fileName = res.data.dir + res.data.gsid + '/' + `${Date.now()}_${Math.random()}`;// 添加必要字段formData.append("key", fileName); // 最终存储的文件名formData.append("policy", res.data.policy);formData.append("OSSAccessKeyId", res.data.accessid);formData.append('success_action_status', "200");formData.append("signature", res.data.signature);formData.append("callback", res.data.callback);formData.append("file", file); // 图片文件 // 发送上传请求const uploadRes = await axios.post(res.data.host, formData);// 获取图片URLconst imageUrl = `${res.data.host}/${uploadRes.data.data.filename}${res.data.style2}`;// const imageUrl = `${res.data.host}/${uploadRes.data.data.filename}${res.data.style1}`;// 插入图片到编辑器this.insertImageToEditor(imageUrl);} catch (error) {console.error('上传失败', error.response ? error.response.data : error.message);}},// 插入图片到编辑器insertImageToEditor(url) {const range = this.$refs.myQuillEditor.quill.getSelection();this.$refs.myQuillEditor.quill.insertEmbed(range.index, 'image', url);this.$refs.myQuillEditor.quill.setSelection(range.index + 1);},async onEditorChange({ html}) {// console.log(quill, "quill");// console.log(text, "text");// console.log(html, "html");this.content = html;this.$emit('content-changed', html); // 发出事件},onEditorBlur(e) {console.log(e, '失去焦点事件');},onEditorFocus(e) {console.log(e, '获得焦点事件');},},};
</script><style lang="less">
.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: "等宽字体";
}.edit_container {width: 100%;
}:deep(.ql-editor) {min-height: 400px;
}
</style>
六、 父页面使用富文本组件
修改的时候直接赋值就可以获取到原来的内容
<template><fuwenben @content-changed="handleContentChange" v-model="editorContent"></fuwenben>
</template>
<script>
import fuwenben from '@/components/fuwenben/fuwenben'
export default {name: "WenZhang",data() {return {editorContent: '',}},methods: {handleContentChange(content) {this.editorContent = content;},}}
</script>
相关文章:
vue富文本 vue-quill-editor + 上传图片到阿里云服务器 + 修改富文本内容
前言 使用富文本编辑器,需要将图片上传到服务器,完成之后,还需要在修改页面完成修改富文本内容,使用的富文本插件是vue-quill-editor, 一 、安装 vue-quill-editor npm i vue-quill-editor npm install quill --save npm inst…...
Java常见设计模式(中):结构型模式
🌈 引言:设计模式就像乐高积木 适配器:让不同形状的积木完美拼接装饰器:给积木添加炫酷灯光效果代理:遥控积木完成复杂动作组合:将小积木搭建成宏伟城堡 结构型模式 主要用于描述对象之间的关系ÿ…...
DeepSeek R1 + 飞书机器人实现AI智能助手
效果 TFChat项目地址 https://github.com/fish2018/TFChat 腾讯大模型知识引擎用的是DeepSeek R1,项目为sanic和redis实现,利用httpx异步处理流式响应,同时使用buffer来避免频繁调用飞书接口更新卡片的网络耗时。为了进一步减少网络IO消耗&…...
【论文详解】Transformer 论文《Attention Is All You Need》能够并行计算的原因
文章目录 前言一、传统 RNN/CNN 存在的串行计算问题二、Transformer 如何实现并行计算?三、Transformer 的 Encoder 和 Decoder 如何并行四、结论 前言 亲爱的家人们,创作很不容易,若对您有帮助的话,请点赞收藏加关注哦ÿ…...
51c嵌入式~电路~合集12
我自己的原文哦~ https://blog.51cto.com/whaosoft/12318429 一、单端、推挽、桥式拓扑结构变压器对比 单端正激式 单端:通过一只开关器件单向驱动脉冲变压器。 正激:脉冲变压器的原/付边相位关系,确保在开关管导通,驱动脉冲…...
php 获取head参数
php 获取head参数 在PHP中,获取HTTP头部(head)参数可以通过不同的方式实现,下面为你详细介绍几种常见的方法。 1. 使用$_SERVER超全局变量 $_SERVER 是PHP中的一个超全局变量,它包含了诸如头信息、路径、脚本位置等…...
蓝桥杯嵌入式备赛
前言 嘿,小伙伴们!备战蓝桥杯嵌入式比赛的号角已经吹响啦!如果你还在为如何入手STM32G431RB这块比赛板子而发愁,别担心,今天我就来给你全方位介绍这块板子,带你快速上手备赛,一起冲向蓝桥杯的赛…...
基于PyTorch实现的自适应注意力卷积网络(AACN)详解
目录 基于PyTorch实现的自适应注意力卷积网络(AACN)详解1. 引言2. 网络结构设计2.1 输入层2.2 初始特征提取层2.3 自适应注意力卷积块(AACB)2.4 下采样与高层特征提取层2.5 全局特征汇聚层2.6 输出层3. 模型优化策略4. 数据集介绍5. PyTorch实现代码详解5.1 完整代码实现5.…...
基于Javase的停车场收费管理系统
基于Javase的停车场收费管理系统 停车场管理系统开发文档 项目概述 1.1 项目背景 随着现代化城市的不断发展,车辆数量不断增加,停车难问题也日益突出。为了更好地管理停车场资 源,提升停车效率,需要一个基于Java SE的停车场管理…...
Cookie与Session:Web开发中的状态管理机制
引言 在Web开发中,HTTP协议是无状态的,这意味着服务器默认不会记住客户端的任何信息。然而,许多应用场景(如用户登录、购物车等)需要服务器能够识别客户端并保持状态。为了解决这个问题,开发者引入了 Cook…...
python量化交易——金融数据管理最佳实践——qteasy创建本地数据源
文章目录 qteasy金融历史数据管理总体介绍本地数据源——DataSource对象默认数据源查看数据表查看数据源的整体信息最重要的数据表其他的数据表 从数据表中获取数据向数据表中添加数据删除数据表 —— 请尽量小心,删除后无法恢复!!总结 qteas…...
手机放兜里,支付宝“碰一下”被盗刷?
大家好,我是小悟。 近期,网络上关于“支付宝‘碰一下’支付易被盗刷”的传言甚嚣尘上,不少用户对此心生疑虑。 首先,要明确一点:“碰一下”支付并不会像某些传言中所描述的那样容易被隔空盗刷。这一观点已经得到了支付…...
C/C++语言知识点一
目录 1. 请对这段代码进行解释:char *const *(*next)( ); 2. 函数指针数组:解释这个表达式char *(*c[10])(int **p); 3. 字符串常量:分析下面这段代码。 4. 访问指定内存地址 5. typedef 和 define 的区别 6. 函数返回局部变量地址问…...
前端面试题---在vue中为什么要用路由
在vue中为什么要用路由, 毕竟a标签可以直接跳转页面 在 Vue 中使用 Vue Router 的主要原因是提高 单页面应用(SPA) 的用户体验和性能。 相比传统的 <a> 标签跳转,Vue Router 提供了以下优势: 避免页面刷新: V…...
Three.js 快速入门教程【十】常见的纹理类型
系列文章目录 Three.js 快速入门教程【一】开启你的 3D Web 开发之旅 Three.js 快速入门教程【二】透视投影相机 Three.js 快速入门教程【三】渲染器 Three.js 快速入门教程【四】三维坐标系 Three.js 快速入门教程【五】动画渲染循环 Three.js 快速入门教程【六】相机控件 Or…...
文档识别-C#中英文文档识别接口-PDF文件内容识别API
文档识别接口可满足用户在数字化转型过程中对文档处理的高效、准确需求。翔云文档识别接口以成熟的文字识别技术、自然语言处理技术、图像识别技术为核心,能够将文档上的非可编辑文本转化为可编辑的数据,从而提升信息处理的速度与实现文档数字化管理的准…...
gRPG协议
gRPG协议是一种用于游戏开发的网络通信协议,全称为Game Real-time Protocol。它主要用于实现实时多人游戏中的数据传输和同步。gRPG协议的设计目标是提供低延迟、高可靠性的数据传输,以支持游戏中的实时互动和状态同步。 gRPG协议的特点 低延迟&#x…...
【maven打包错误】 无效的目标发行版:16
maven打包错误 错误截图 About 故事在一个风和日丽的下午,我一如往常的摸鱼,突如其来的事情打乱我的摸鱼节奏,“为什么测试不能用了” ,随着前端帅哥一声轻咦,故事便开始了,我检查发现是是磁盘满了&#x…...
Oracle 查询表空间使用情况及收缩数据文件
本文介绍Oracle收缩数据文件的相关操作,运维工作中有时会需要通过收缩数据文件来释放磁盘空间。 数据文件初始化方式: 1.我们创建表空间一般有两种方式初始化其数据文件,即指定初始大小为32G(很大的值)或指定初始大小为…...
Transformer 代码剖析1 - 数据处理 (pytorch实现)
引言 Transformer 架构自《Attention Is All You Need》论文发表以来,在自然语言处理领域引起了巨大的变革。它摒弃了传统的循环结构,完全基于注意力机制,显著提高了处理序列数据的效率和性能。本文将通过对一个具体的项目代码结构进行详细分…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...
比较数据迁移后MySQL数据库和OceanBase数据仓库中的表
设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...
yaml读取写入常见错误 (‘cannot represent an object‘, 117)
错误一:yaml.representer.RepresenterError: (‘cannot represent an object’, 117) 出现这个问题一直没找到原因,后面把yaml.safe_dump直接替换成yaml.dump,确实能保存,但出现乱码: 放弃yaml.dump,又切…...
2025年- H71-Lc179--39.组合总和(回溯,组合)--Java版
1.题目描述 2.思路 当前的元素可以重复使用。 (1)确定回溯算法函数的参数和返回值(一般是void类型) (2)因为是用递归实现的,所以我们要确定终止条件 (3)单层搜索逻辑 二…...
Spring事务传播机制有哪些?
导语: Spring事务传播机制是后端面试中的必考知识点,特别容易出现在“项目细节挖掘”阶段。面试官通过它来判断你是否真正理解事务控制的本质与异常传播机制。本文将从实战与源码角度出发,全面剖析Spring事务传播机制,帮助你答得有…...
qt 双缓冲案例对比
双缓冲 1.双缓冲原理 单缓冲:在paintEvent中直接绘制到屏幕,绘制过程被用户看到 双缓冲:先在redrawBuffer绘制到缓冲区,然后一次性显示完整结果 代码结构 单缓冲:所有绘制逻辑在paintEvent中 双缓冲:绘制…...
