17网站一起做网店杭州/国际新闻最新消息10条
第一步在vue2项目下安装
npm install --save @ckeditor/ckeditor5-build-decoupled-document
第二 项目下新建一个plugins的文件夹将这个包ckeditor5-build-classic放入
(包在页面最上方 有个下载按钮 可以下载)
刚开始时 ckeditor5-build-classic文件夹下无node_modules,需要找到 项目下的ruoyi-ui\src\plugins\ckeditor5-build-classic文件地址,cmd打开,然后输入npm install 安装下 ckeditor5-build-classic文件夹下就有这个了node_modules
第三步 (为了兼容wold和pdf的粘贴)
找到plugins\ckeditor5-build-classic\node_modules@ckeditor\ckeditor5-paste-from-office\src\filters\image.js 这个文件,然后打开,搜索regexPictureHeader,将某段代码进行替换如下
//图片替换
regexPictureHeader = /{\pict[\s\S]+?({\*\blipuid\s?[\da-fA-F]+})+?/;
第四步 (为了兼容wold和pdf的粘贴)
找到plugins\ckeditor5-build-classic\node_modules@ckeditor\ckeditor5-paste-from-office\src\filters\space.js 这个文件 ,然后打开,搜索htmlDocument.querySelectorAll,将这段代码替换如下
htmlDocument.querySelectorAll('span[style*=spacerun]').forEach(el => {if (/[^\b]/.test(el.innerText.trim()) === false) {const innerTextLength = el.innerText.length || 0;el.innerHTML = Array(innerTextLength + 1).join('\u00A0 ').substr(0, innerTextLength);}});
第五步 在api文件下新建upload.js
import { getToken } from "@/utils/auth";
// upload.js中
class MyUploadAdapter {constructor(loader) {// 要在上载期间使用的文件加载器实例this.loader = loader;}// 启动上载过程upload() {return this.loader.file.then((file) =>new Promise((resolve, reject) => {this._initRequest();this._initListeners(resolve, reject, file);this._sendRequest(file);}));}// 中止上载过程abort() {if (this.xhr) {this.xhr.abort();}}// 使用传递给构造函数的URL初始化XMLHttpRequest对象._initRequest() {const xhr = (this.xhr = new XMLHttpRequest());// 后端上传图片接口 `${process.env.VUE_APP_BASE_API}/common/upload`,xhr.open("POST",`${process.env.VUE_APP_BASE_API}/common/upload`,true);xhr.responseType = "json";}// 初始化 XMLHttpRequest 监听._initListeners(resolve, reject, file) {const xhr = this.xhr;const loader = this.loader;const genericErrorText = `无法上传文件: ${file.name}.`;xhr.addEventListener("error", () => reject(genericErrorText));xhr.addEventListener("abort", () => reject());xhr.addEventListener("load", () => {//这个例子假设XHR服务器的“response”对象将附带//一个“error”,它有自己的“message”,可以传递给reject()//你的集成可能以不同的方式处理上传错误,所以请确保//当上传失败时,必须调用reject()函数。const response = xhr.response;// 当上传失败时,必须调用reject()函数。if (!response || response.error) {// reject方法会调用浏览器的alert事件 并清除页面上的图片展示return reject(response && response.error? response.error.message: genericErrorText);}// 上传成功,从后台获取图片的url地址// resolve方法会将default中的值插入到页面中img标签的src中resolve({default: response.url,});});// 支持时上传进度。文件加载器有#uploadTotal和#upload属性,用于在编辑器用户界面中显示上载进度栏。if (xhr.upload) {xhr.upload.addEventListener("progress", (evt) => {if (evt.lengthComputable) {loader.uploadTotal = evt.total;loader.uploaded = evt.loaded;}});}}// 准备数据并发送请求_sendRequest(file) {// 通过FormData构造函数创建一个空对象const data = new FormData();// 通过append()方法在末尾追加key为files值为file的数据data.append("file", file); // 上传的参数data/*** 重要提示:这是实现诸如身份验证和CSRF保护等安全机制的正确位置。* 例如,可以使用XMLHttpRequest.setRequestHeader()设置包含应用程序先前生成的CSRF令牌的请求头。*/this.xhr.setRequestHeader("Authorization", getToken());this.xhr.send(data);}
}function MyCustomUploadAdapterPlugin(editor) {editor.plugins.get('FileRepository').createUploadAdapter = (loader) => {// 在这里将URL配置为后端上载脚本return new MyUploadAdapter(loader)}
}export {MyUploadAdapter,MyCustomUploadAdapterPlugin
}
第六步
组件页面 components/CkEditor/index.vue
<template><div><div :id="editorID"></div></div>
</template><script>import {MyCustomUploadAdapterPlugin,MyUploadAdapter} from "@/api/upload";import ClassicEditor from "@/plugins/ckeditor5-build-classic";import "@/plugins/ckeditor5-build-classic/build/translations/zh-cn.js";export default {props: {/* 编辑器的内容 */ckEditorValue: {type: String,default: "",},/* 只读模式 */readOnly: {type: Boolean,default: false,},/* 控制什么时候显示工具条 */inEditorShow: {type: Boolean,default: true,},/* editorID */editorID: {type: String,default: 'editor',}},data() {return {editor: ''}},watch: {ckEditorValue: {handler(newVal) {var that = this;setTimeout(() => {if (that.editor != '' && that.editor != null && that.editor != undefined)that.editor.setData(that.ckEditorValue);}, 100)},immediate: true,deep: true},readOnly: {handler(newVal) {var that = this;setTimeout(() => {if (newVal) {if (that.editor != '' && that.editor != null && that.editor != undefined)that.editor.enableReadOnlyMode('editor');} else {if (that.editor != '' && that.editor != null && that.editor != undefined)that.editor.disableReadOnlyMode('editor');}}, 100)},immediate: true,deep: true}},mounted() {this.initEditor();},methods: {initEditor() {let that = this;ClassicEditor.create(document.querySelector(`#${that.editorID}`), {language: 'zh-cn',extraPlugins: [MyCustomUploadAdapterPlugin],placeholder: '请输入内容....',autosave: {waitingTime: 100,save(editor) {// return that.saveData(editor.getData());sessionStorage.setItem("saveEditorData", editor.getData());},}}).then((editor) => {// 设置富文本高度editor.editing.view.change(writer => {writer.setStyle('min-height', '500px', editor.editing.view.document.getRoot());});// 上传文件editor.plugins.get("FileRepository").createUploadAdapter = (loader) => {return new MyUploadAdapter(loader);};//富文本是否只读if (this.readOnly) {editor.enableReadOnlyMode('editor');} else {editor.disableReadOnlyMode('editor');}//根据父组件判断是否显示工具栏if (!this.inEditorShow) {var toolbar = document.getElementsByClassName('ck-toolbar');var border = document.getElementsByClassName('ck-editor__editable_inline');toolbar[0].style.display = 'none';border[0].style.border = 'none';}editor.setData(that.ckEditorValue);that.editor = editor;}).catch((error) => console.error(error));},clear() {this.editor.setData('');}}}
</script><style>.ck-body-wrapper {position: absolute;z-index: 3000;}.ck a {color: rgb(24, 144, 255);}
</style><style lang="scss" scoped>
</style>
第七步 页面引用
<template><CkEditor :ckEditorValue="dataForm.storageAndUse" @saveEditorData="saveEditorData"></CkEditor>
</template>
<script>import CkEditor from "../components/CkEditor/index.vue";export default {components:{CkEditor},data() {return {dataForm: {id: null,storageAndUse: null //试剂的保存与使用},}}
相关文章:

vue+ckEditor5 复制粘贴wold文字+图片并保存格式
第一步在vue2项目下安装 npm install --save ckeditor/ckeditor5-build-decoupled-document 第二 项目下新建一个plugins的文件夹将这个包ckeditor5-build-classic放入 (包在页面最上方 有个下载按钮 可以下载) 刚开始时 ckeditor5-build-classic文件…...

redis列表若干记录
2、列表 ziplist ziplist参数 entry结构 entry-data:节点存储的元素prelen:记录前驱节点长度encoding:当前节点编码格式encoding encoding属性 使用多个子节点存储节点元素长度,这种多字节数据存储在计算机内存中或者进行网络传输的时的字节…...

固态硬盘用mbr还是GPT?固态硬盘分区类型用mbr还是GPT分析
固态硬盘用mbr还是GPT?答:固态硬盘分区类型用mbr还是gpt其实取决于你对分区要求及引导模式。我们知道现在的引导模式有uefi和legacy两种引导模式,如果采用的是uefi引导模式,分区类型对应的就是gpt分区(guid),如果引导模…...

http/sse/websocket 三大协议演化历史以及 sse协议下 node.js express 服务实现打字机案例 负载均衡下的广播实现机制
背景 自从2022年底chatgpt上线后,sse就进入了大众的视野,之前是谁知道这玩意是什么?但是打字机的效果看起来是真的很不错,一度吸引了很多人的趋之若鹜,当然了这个东西的确挺好用,而且实现很简单࿰…...

智能时代新宠:2024年录音转文字软件
无论是学生群体记录课堂笔记,职场人士整理会议纪要,还是自媒体创作者捕捉灵感火花,录音转文字软件都以其独特的便利性和高效性赢得了广泛的好评。今天,就让我们一起探索那些深受大家喜爱的录音转文字工具吧。 1.365在线转文字 链…...

【Python机器学习】树回归——使用Python的tkinter库创建GUI
机器学习给我们提供了一些强大的工具,能从未知数据中抽取出有用的信息。因此,能否这些信息以易于人们理解的方式呈现十分重要。如果人们可以直接与算法和数据交互,将可以比较轻松的进行解释。其中一个能够同时支持数据呈现和用户交互的方式就…...

谷歌浏览器网页底图设置为全黑
输入网址:chrome://flags/ 搜索dark,选择Enabled,重启浏览器即可...

Unity | AmplifyShaderEditor插件基础(第二集:模版说明)
目录 一、前言 二、核心模版和URP模版 1.区别介绍 2.自己的模版 三、输出节点 1.界面 2.打开OutPut 3.ShderType 4.ShaderName 5.Shader大块内容 6.修改内容 四、预告 一、前言 内容全部基于以下链接基础以上讲的。 Unity | Shader基础知识(什么是shader…...

【Linux入门】Linux常见指令
目录 前言 一、Linux基本指令 1.ls指令 2.pwd命令 3.cd 指令 4.touch指令 5.mkdir指令 6.rmdir指令 && rm 指令 7.man指令 8.cp指令 9.mv指令 10.cat 11.date 12.top 13.shutdown-关机 14.重要的几个热键 二、Linux扩展指令 总结 前言 Linux指令是在…...

startData
某音startData 记得加入学习群: python爬虫&js逆向3 714283180...

CV每日论文--2024.7.24
1 、AutoAD-Zero: A Training-Free Framework for Zero-Shot Audio Description 中文标题:T2V-CompBench:组合文本到视频生成的综合基准AutoAD-Zero:零样本音频描述的免训练框架 简介:我们的目标是以无需训练的方式为电影和电视剧…...

大语言模型的简易可扩展增量预训练策略
前言 原论文:Simple and Scalable Strategies to Continually Pre-train Large Language Models翻译文件已整理至Github项目Some-Paper-CN,欢迎大家Star! 摘要 大语言模型(LLMs)通常需要在数十亿个tokens上进行预训…...

python学习之异常
在编程中,异常是指程序运行时发生的错误或异常情况,它们可能会打断程序的正常流程。不同的编程语言定义了自己的一套异常类型。在Python中,异常是基于类和对象的,所有的异常都继承自内置的BaseException类。 以下是Python中一些常…...

多张图像实现全景无痕拼接操作
目录 编辑 1,图像拼接的作用 2,实现步骤 3,效果展示 1,图像拼接的作用 视觉扩展:通过拼接,可以将多个视角的图像合并,创造出比单张图片更广阔的视野。 数据整合:在科学研究和地…...

在阿里云ecs上构建一个WordPress博客网站
1、购买ECS 使用抢占式实例,RDS 使用按量付费 2、在安全组的出入方向添加80端口 3、购买一个公网IP绑定该ecs 4、云数据库rds选择按量付费 5、创建一个名为test_user的普通账号 6、创建数据库 7、设置RDS实例白名单 8、远程登录ecs实例 9、安装apache服务及其扩展包…...

安卓应用开发学习:查看手机传感器信息
一、引言 在手机app的开发中经常会用到手机的传感器,在《Android App 开发进阶与项目实战》一书的第10章就介绍了传感器的一些功能和用法。要想使用传感器,首先得知道手机具备哪些传感器。书中有传感器类型取值的说明,并提供了一个查看手机传…...

C语言字符串缺陷
目录 补缺: 正题开始: 思考: 解决方案: 1.string类 2.redis库 简介: 对于处理字符串的好处: 下期预告:内容待定 补缺: 在上期内容的结尾我留下了一个问题,这个问…...

分布式场景中的常见的技术问题及解决,如分布式锁、分布式事务、分布式 session、分布式任务调度
目录 一、分布式锁 二、分布式事务 三、分布式Session 四、分布式任务调度 在分布式场景中,常见的技术问题及其解决方案涉及多个方面,包括分布式锁、分布式事务、分布式session和分布式任务调度。以下是对这些问题的详细探讨: 一、分布式…...

Android笔试面试题AI答之Kotlin(9)
文章目录 39.Kotlin中List与MutableList的区别?ListMutableList使用场景示例 40. Kotlin中实现单例的几种常见方式?1. 懒汉式(线程不安全)2. 懒汉式(线程安全)3. 饿汉式4. 双重校验锁(DCL, Doub…...

C# 不一样的洗牌算法---Simd指令
洗牌算法,以随机打乱数组中元素的位置 测试数据创建 int[] _data; Random rng new Random(); protected override void CreateData() {_data new int[_size];for (int i 0; i < _data.Length; i){_data[i] i;} } 普通打乱数组元素位置 protected overrid…...

LVGL系列3--纯物理(外部)按键,数字键盘控制控件
LVGL系列 一、LVGL移植 LVGL系列1–AT32移植LVGL_V8具体步骤 LVGL系列2–linux lvglv8 vscode 移植 LVGL系列3–纯物理(外部)按键,数字键盘控制控件 文章目录 LVGL系列一、LVGL移植 一、背景方式一:自定义事件发送与处理函数方式二:利用l…...

FPGA开发——UART回环实现之接收模块的设计
一、简介 因为我们本次进行串口回环的实验的对象是FPGA开发板和PC端,所以在接收和发送模块中先编写接收模块,这样可以在后面更好的进行发送模块的验证。(其实这里先编写哪个模块)都不影响,这里看自己心情,反…...

Debezium系列之:记录一次SQLServer数据库数据不采集,恢复采集造成下游承压的情况,以及相对应的详细解决方案
Debezium系列之:记录一次SQLServer数据库数据不采集,恢复采集造成下游承压的情况,以及相对应的详细解决方案 一、背景二、查看CDC表情况三、 排查数据库是否开启代理四、排查表是否开启CDC五、下游承压情况六、解决方案一、背景 Connector状态正常,但几十台SQLServer数据库…...

Linux线程基础学习记录
0.线程特点 (1).线程共享资源:一个进程下的多个线程共享以下资源 可执行的指令 静态数据 进程中打开的文件描述符 当前工作目录 用户ID 用户组ID (2).线程私有资源: 线程ID PC(程序计数器)和相…...

【Python学习-UI界面】PyQt5 小部件12-QStackedWidget 多页显示
功能和 QTabWidget 类似,它也有助于高效利用窗口的客户区域。 QStackedWidget 提供了一个窗口堆栈,每次只能查看一个窗口。它是建立在 QStackedLayout 之上的一个有用的布局。 样式如下: 右键可以变型为QTabWidget...

Mybatis中好用的元对象反射工具类 - MetaObject
一、前言 在获取map对象或者是其他深层嵌套对象,如果你的做法是挨个取出判空然后继续再向下查找,那么可以看看本文的方案,它或许能让你打开新的思路。 作为一名java开发人员,Mybatis几乎是我们无法避开的ORM框架,如果你…...

javaEE WebServlet、SpringWebMVC、SpringBoot实现跨域访问的4种方式及优先级,nginx配置跨域
文章目录 1. 前置知识2. 原理和解决方案总结2.1. 跨域不通过原理流程图2.2. 实现原理:添加以下http响应头2.3. 四种跨域实现方式及优先级(从高到低) 3. 具体实现代码3.1. 跨域全局配置方式-Filter(全适用)3.2. 跨域全局配置方式-SpringMvc3.3…...

深入理解JavaScript性能优化:从基础到高级
引言 在当今快速发展的Web世界中,性能已经成为衡量应用质量的关键指标。随着Web应用复杂度的不断提升,JavaScript作为前端开发的核心语言,其性能优化变得尤为重要。本文旨在全面深入地探讨JavaScript性能优化的各个方面,从基础概念到高级技巧,帮助开发者构建高效、流畅的Web应用…...

java+springboot实现定时任务
由于是初级程序员,基于注解的形式实现了一个简单的定时任务; 1. 使用Scheduled注解 Spring的Scheduled注解是一种非常简单和便捷的实现定时任务的方式。通过在方法上添加Scheduled注解,我们可以指定方法在特定的时间间隔或固定的时间点执行…...

1.3 数据库的发展历史与演变
欢迎来到我的博客,很高兴能够在这里和您见面!欢迎订阅相关专栏: 工💗重💗hao💗:野老杂谈 ⭐️ 全网最全IT互联网公司面试宝典:收集整理全网各大IT互联网公司技术、项目、HR面试真题.…...