【前端】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、pasteckeditor.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);};}}});// 处理tabckeditor.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对应XML的API,method: 'POST',headers: {'Content-Type': 'application/json','token': 用户token,},data: formData,}).then((res) => {this.xmlInput = res.data;this.convertXmlToBase64();});},// 将 XML 转换为 Base64convertXmlToBase64() {if (this.xmlInput) {const xmlText = this.xmlInput;const base64 = btoa(encodeURIComponent(xmlText));this.base64Output = base64;} else {alert('Please enter some XML first.');}},// 将 Base64 转换为 HTMLconvertBase64ToHtml() {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文件都能转成富文本,让用户能在网页上编辑和保存文档。