【前端】Vue中使用CKeditor作为富文本编辑器

news2025/6/4 9:58:58

官网https://ckeditor.com/
此处记录一下我在使用的时候具体初始化的代码。

<template>
  <div>
    <textarea :id="id"></textarea>
  </div>
</template>

<script>
export default {
  name: 'CkEditor',
  data: function () {
    return {
      id: parseInt(Math.random() * 10000).toString(),
      ckeditor: null,
    };
  },

  // 初始化
  mounted: function () {
    const self = this;
    let CKEDITOR = window.CKEDITOR;

    let ckeditor = window.CKEDITOR.replace(self.id, {
      height: 500,
      language: 'en',
      allowedContent: true,
      pasteFilter: null,
      toolbar: [
        {
          name: 'code',
          items: ['Source'],
        },
        {
          name: 'basicstyles',
          items: [
            'Styles',
            '-',
            'Bold',
            'Italic',
            'Strike',
            'Underline',
            'TextColor',
            'BGColor',
            'Font',
            'FontSize',
          ],
        },
        {
          name: 'styles',
          items: ['RemoveFormat'],
        },
        {
          name: 'insert',
          items: ['Table', 'SpecialChar', 'HorizontalRule'],
        },
        '/',
        {
          name: 'paragraph',
          items: [
            'Format',
            'NumberedList',
            'BulletedList',
            '-',
            'Indent',
            'Outdent',
            '-',
            'JustifyLeft',
            'JustifyCenter',
            'JustifyRight',
            'lineheight',
          ],
        },
        {
          name: 'links',
          items: [
            'Link',
            'Unlink',
            '-',
            'Subscribe',
            'Unsubscribe',
            'HtmlTemplate',
          ],
        },
        {
          name: 'document',
          items: ['Undo', 'Redo'],
        },
      ],
    });
    // 处理图片copy、paste
    ckeditor.on('paste', async (evt) => {
      if (evt.data.dataTransfer.getFilesCount() > 0) {
        evt.data.dataValue = '';
        if (evt.data.dataTransfer.getFilesCount()) {
          let file = evt.data.dataTransfer.getFile(0);
          const reader = new FileReader();
          reader.readAsDataURL(file);
          reader.onload = () => {
            self.ckeditor.insertHtml(`<img src="${reader.result}"/>`);
          };
          reader.onerror = (error) => {
            console.error(error);
          };
        }
      }
    });
    // 处理tab
    ckeditor.on('key', function (event) {
      let keycode = event.data.keyCode;
      if (keycode === 9) {
        event.cancel();
        ckeditor.execCommand('indent');
      }
    });
    // 监听内容变更事件
    ckeditor.on('instanceReady', () => {
      self.ckeditor = ckeditor;
    }); 
    ckeditor.on('change', function () {
      console.log(self.ckeditor.getData());
    });

    setTimeout(() => {
      // 回显
      this.insertDiv(
        `<html>请输入文本</html>`,
      );
    }, 5000);
  },

  methods: {
    // 触发
    insertDiv(data) {
      this.ckeditor.insertHtml(data);
    },
  },
};
</script>

开发的时候遇到新的问题:HTML串无法由后端直接解析得到,于是在触发insertDiv函数之前补充了一段【word文档->xml->Base64->HTML串】的处理

<template>
  <div>
    <h1>XML 转 Base64 转 HTML</h1>
    <textarea v-model="xmlInput" placeholder="输入XML"></textarea>
    <button @click="convertXmlToBase64">Convert XML to Base64</button>
    
    <div v-if="base64Output">
      <h2>Base64 为:</h2>
      <textarea v-model="base64Output" readonly></textarea>
      <button @click="convertBase64ToHtml">Convert Base64 to HTML</button>
    </div>
    
    <div v-if="htmlOutput">
      <h2>HTML 为:</h2>
      <div style="color: #fff" v-html="htmlOutput"></div>
    </div>
  </div>
</template>

<script>
import axios from 'axios';

export default {
  name: 'CkEditor',
  data() {
    return {
      xmlInput: '',
      base64Output: '',
      htmlOutput: ''
    };
  },
  methods: {
    init() {
      const formData = new FormData();
      formData.append('filePath', 后端文件路由);
      axios({
        url: 后端生成word对应XMLAPI,
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'token': 用户token,
        },
        data: formData,
      }).then((res) => {
        this.xmlInput = res.data;
        this.convertXmlToBase64();
      });
    },

    // 将 XML 转换为 Base64
    convertXmlToBase64() {
      if (this.xmlInput) {
        const xmlText = this.xmlInput;
        const base64 = btoa(encodeURIComponent(xmlText));
        this.base64Output = base64;
      } else {
        alert('Please enter some XML first.');
      }
    },
    // 将 Base64 转换为 HTML
    convertBase64ToHtml() {
      if (this.base64Output) {
        const decodedXml = decodeURIComponent(atob(this.base64Output));
        const parser = new DOMParser();
        const xmlDoc = parser.parseFromString(decodedXml, 'text/xml');
        this.htmlOutput = xmlDoc.documentElement.outerHTML; // 直接使用 outerHTML 保留格式
      } else {
        alert('Please convert XML to Base64 first.');
      }
    }
  }
};
</script>

<style>
textarea {
  width: 100%;
  height: 100px;
}
</style>

最后成功实现每个word文件都能转成富文本,让用户能在网页上编辑和保存文档。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2396312.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【计算机系统结构】习题2

目录 1.有一条静态多功能流水线由5段组成&#xff0c;加法用1、2、4、5段&#xff0c;乘法用1、3、5段&#xff0c;第3段时间为&#xff0c;其余各段为&#xff0c;且流水线的输出可直接返回输入端或暂存器&#xff0c;若计算&#xff0c;试计算吞吐量、加速比、效率 2.有一动…

用户资产化视角下开源AI智能名片链动2+1模式S2B2C商城小程序的应用研究

摘要&#xff1a;在数字化时代&#xff0c;平台流量用户尚未完全转化为企业的数字资产&#xff0c;唯有将其沉淀至私域流量池并实现可控、随时触达&#xff0c;方能成为企业重要的数字资产。本文从用户资产化视角出发&#xff0c;探讨开源AI智能名片链动21模式S2B2C商城小程序在…

机器学习实验七--SVM垃圾邮件分类器

SVM垃圾邮件分类器 一、什么是SVM二、实例&#xff1a;垃圾邮件分类器1.实验要求2.原理解释2.1 数据预处理流程2.2 特征提取方法2.3 SVM分类器 3.代码实现4.实验结果5.实验总结 一、什么是SVM 支持向量机(Support Vector Machine, SVM)是一种监督学习算法&#xff0c;主要用于…

C++23 std::fstreams基础回顾

文章目录 引言1.1 std::fstreams概述1.2 std::fstreams的主要功能和常用操作 2. 独占模式 (P2467R1) 的详细介绍2.1 独占模式的定义和背景2.2 独占模式的作用和优势 3. C23 std::fstreams支持独占模式 (P2467R1) 的具体实现方式3.1 代码示例3.2 实现步骤解释 4. 使用该特性可能…

Git初识Git安装

目录 1. Git初识 1.1 提出问题 1.2 如何解决--版本控制器 1.3 注意事项 2 Git安装 2.1 Centos 2.2 Ubuntu 2.3 Windows 1. Git初识 1.1 提出问题 不知道你工作或学习时&#xff0c;有没有遇到这样的情况&#xff1a;我们在编写各种文档时&#xff0c;为了防止文档丢失…

使用Redisson实现分布式锁发现的【订阅超时】Subscribe timeout: (7500ms)

背景 使用 redisson 实现分布式锁&#xff0c;出现的异常&#xff1a; org.redisson.client.RedisTimeoutException: Subscribe timeout: (7500ms). Increase ‘subscriptionsPerConnection’ and/or ‘subscriptionConnectionPoolSize’ parameters 从异常信息读的出来一些东…

如何使用 poetry 创建虚拟环境,VSCode 如何激活使用 Poetry 虚拟环境(VSCode如何配置 Poetry 虚拟环境)

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 使用 Poetry 创建和激活虚拟环境 📒🧪 创建项目并初始化 Poetry🔧 配置虚拟环境创建位置✅ 指定Python版本📦 安装依赖并创建虚拟环境🚀 激活虚拟环境📒 在 VSCode 中配置 Poetry 虚拟环境 📒🧭 方法一:使用 V…

牛客小白月赛117

前言&#xff1a;solveABCF相对简单&#xff0c;D题思路简单但是实现麻烦&#xff0c;F题郭老师神力b(&#xffe3;▽&#xffe3;)。 A. 好字符串 题目大意&#xff1a;给定字符串s&#xff0c;里面的字母必须大小写同时出现。 【解题】&#xff1a;没什么好说的&#xff0…

美化显示GDB调试的数据结构

笔者在前面的博文记一次pdf转Word的技术经历中有使用到mupdf库&#xff0c;该库是使用C语言写的一个操作PDF文件的库&#xff0c;同时提供了Python接口&#xff0c;Java接口和JavaScript接口。 在使用该库时&#xff0c;如果想要更高的性能&#xff0c;使用C语言接口是不二的选…

一篇学习CSS的笔记

一、简介 Cascading Style Sheets简称CSS&#xff0c;中文翻译为层叠样式表。当HTML被发明出来初期&#xff0c;不同的浏览器提供了各种各样的样式语言给用户控制网页的效果&#xff0c;HTML包含的显示属性并不是很多。但是随着各种使用者对HTML的需求&#xff0c;HTML添加了大…

StarRocks x Iceberg:云原生湖仓分析技术揭秘与最佳实践

导读&#xff1a; 本文将深入探讨基于 StarRocks 和 Iceberg 构建的云原生湖仓分析技术&#xff0c;详细解析两者结合如何实现高效的查询性能优化。内容涵盖 StarRocks Lakehouse 架构、与 Iceberg 的性能协同、最佳实践应用以及未来的发展规划&#xff0c;为您提供全面的技术解…

笔试笔记(运维)

&#xff08;数据库&#xff0c;SQL&#xff09; limit1 随机返回其中一个聚合函数不可以嵌套使用 【^】这个里面的数据任何形式组合都没有 sql常用语句顺序&#xff1a;from-->where-->group by-->having-->select-->order by-->limit 只要其中一个表存在匹…

使用langchain实现五种分块策略:语义分块、父文档分块、递归分块、特殊格式、固定长度分块

文章目录 分块策略详解1. 固定长度拆分&#xff08;简单粗暴&#xff09;2. 递归字符拆分&#xff08;智能切割&#xff09;3. 特殊格式拆分&#xff08;定向打击&#xff09;Markdown分块 4. 语义分割&#xff08;更智能切割&#xff09;基于Embedding的语义分块基于模型的端到…

【项目记录】登录认证(下)

1 过滤器 Filter 刚才通过浏览器的开发者工具&#xff0c;可以看到在后续的请求当中&#xff0c;都会在请求头中携带JWT令牌到服务端&#xff0c;而服务端需要统一拦截所有的请求&#xff0c;从而判断是否携带的有合法的JWT令牌。 那怎么样来统一拦截到所有的请求校验令牌的有…

linux文件管理(补充)

1、查看文件命令 1.1 cat 用于连接文件并打印到标准输出设备上&#xff0c;它的主要作用是用于查看和连接文件。 用法&#xff1a; cat 参数 文件名 参数&#xff1a; -n&#xff1a;显示行号&#xff0c;会在输出的每一行前加上行号。 -b&#xff1a;显示行号&#xff0c;…

Python训练营---Day42

DAY 42 Grad-CAM与Hook函数 知识点回顾 回调函数lambda函数hook函数的模块钩子和张量钩子Grad-CAM的示例 作业&#xff1a;理解下今天的代码即可 1、回调函数 回调函数&#xff08;Callback Function&#xff09;是一种特殊的函数&#xff0c;它作为参数传递给另一个函数&#…

基于空天地一体化网络的通信系统matlab性能分析

目录 1.引言 2.算法仿真效果演示 3.数据集格式或算法参数简介 4.MATLAB核心程序 5.算法涉及理论知识概要 5.1 QPSK调制原理 5.2 空天地一体化网络信道模型 5.3 空天地一体化网络信道特性 6.参考文献 7.完整算法代码文件获得 1.引言 空天地一体化网络是一种将卫星通信…

c++ opencv 形态学操作腐蚀和膨胀

https://www.jb51.net/article/247894.htm(上图图片来自这个博客) https://codec.wang/docs/opencv/basic/erode-and-dilate&#xff08;上图图片参考博客&#xff09; cv::Mat kernel cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3)); cv::erode(src, dst, kern…

【c++】【数据结构】红黑树

目录 红黑树的定义红黑树的部分模拟实现颜色的向上更新旋转算法单旋算法双旋算法 红黑树与AVL树的对比 红黑树的定义 红黑树是一种自平衡的二叉搜索树&#xff0c;通过特定的规则维持树的平衡。红黑树在每个结点上都增加一个存储位表示结点的颜色&#xff0c;结点的颜色可以是…

基于SpringBoot+Redis实现RabbitMQ幂等性设计,解决MQ重复消费问题

解决MQ重复消费问题 一、实现方案 本方案参考 「RabbitMQ消息可靠性深度解析&#xff5c;从零构建高可靠消息系统的实战指南」&#xff0c;向开源致敬&#xff01; 1、业务层幂等处理&#xff1a; 每个消息携带一个全局唯一ID&#xff0c;在业务处理过程中&#xff0c;首先检查…