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

官网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(`${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(
        `请输入文本`,
      );
    }, 5000);
  },

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

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

<template>
  <div>
    <h1>XML 转 Base64 转 HTMLh1>
    <textarea v-model="xmlInput" placeholder="输入XML">textarea>
    <button @click="convertXmlToBase64">Convert XML to Base64button>
    
    <div v-if="base64Output">
      <h2>Base64 为:h2>
      <textarea v-model="base64Output" readonly>textarea>
      <button @click="convertBase64ToHtml">Convert Base64 to HTMLbutton>
    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文件都能转成富文本,让用户能在网页上编辑和保存文档。

你可能感兴趣的:(前端,前端,vue.js,javascript)