ckeditor4 在vue中使用的坑!!!

3,850 阅读1分钟

首先我在寻找一款功能齐全的,可以在vue中使用的富文本编辑器,偶然发现了ckeditor 这个富文本编辑器,我靠真的很强大!!!

然后我就发现了 ckeditor4-vue 这个插件 然后我就安装了,后来发现功能真特码少(不知道是不是我没有看全)

然后我就没用 首先把包 放到 public 目录下面

然后修改index.html 引入js

然后自定义一个vue组件

在使用的过程中你会发现一个坑 巨坑 就是你的富文本弹框的时候 你把路由返回上一层 弹框没有隐藏下去,因为 这玩意把弹框都放到body 里面了 坑

不要急 我是这么解决的 我监听了路由变化在 APP.vue 中监听 为啥呢 因为吧 因为吧 放在组件监听 返回上一层就消失了监听不到了 不信你试试 最后 图片上传的问题 添加了一个插件 主要就是plugin.js 的写法

/*
 Copyright (c) 2019, Weison. All rights reserved. 
*/
(function() {
	CKEDITOR.plugins.add('uploads', {
		icons: 'uploads',
		init: function(editor) {
			// 创建指令
			editor.addCommand('uploads', {
				exec:function(editor){
					// 请求方法
					// var url = editor.config.uploads().url || editor.config.filebrowserUploadUrl;
					choice().click();
					// 选择对象
					function choice() {
						return window.uic || (function() {
							var ne = document.createElement('input');
							ne.setAttribute('type', 'file');
							ne.setAttribute('multiple', 'multiple');
							ne.setAttribute('accept', 'image/*');
							ne.style.display = 'none';
							document.body.appendChild(ne);
							return window.uic = ne;
						})();
					}
					// 事件处理
					choice().onchange = function() {
						var fs = window.uic.files;
						// 空触发
						if (fs.length == 0) {
							return false;
						}
						// 构造对象
						var uio = window.uio || (window.uio = []);
						for (var i = 0; i < fs.length; i++) {
							var o = {};
							o.file = fs[i];
							uio.push(o);
						}
						// 调用自定义上传方法
						editor.config.uploads().uploadFun(editor, uio)
					};
					// function http(obj) {
					// 	if (!url) {
					// 		return alert('未配置上传URL');
					// 	}
					// 	// 创建标识
					// 	ups[obj.file.name] = true;
					// 	// 创建进度
					// 	// obj.progress = progress();
					// 	// obj.div.appendChild(obj.progress);
					// 	// obj.progress.onclick = function() {
					// 	// 	!obj.src && http(obj);
					// 	// }
					// 	// Ajax 请求
					// 	var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
					// 	xhr.onreadystatechange = function() {
					// 		if (xhr.readyState == 4 && xhr.status == 200) {
					// 			var ret = JSON.parse(xhr.responseText || '{}');
					// 			// 在这里可以自定义上传图片的功能
					// 			if (ret.uploaded == 1 || ret.code === 200) {
					// 				obj.src = ret.url;
					// 				obj.progress.title = '上传成功';
					// 				obj.progress.setAttribute('style', percentage(100, true));
					// 			} else {
					// 				delete obj.src;
					// 				var msg = (ret.error || {}).message;
					// 				obj.progress.title = (msg ? msg + ',' : '') + '点击重新上传';
					// 				obj.progress.setAttribute('style', percentage(100, false));
					// 			}
					// 		}
					// 	}
					// 	// 完成删除
					// 	xhr.onloadend = function(e) {
					// 		delete ups[obj.file.name];
					// 	};
					// 	// 进度更新
					// 	xhr.onprogress = function(e) {
					// 		if (e.lengthComputable) {
					// 			obj.progress.setAttribute('style', percentage(e.loaded / e.total * 100, true))
					// 		}
					// 	};
					// 	// 错误提示
					// 	xhr.onerror = function(e) {
					// 		obj.progress.setAttribute('style', percentage(100, false));
					// 		obj.progress.title = '点击重新上传';
					// 	};
					// 	// 提交请求
					// 	xhr.open("POST", url, true);
					// 	var fd = new FormData();
					// 	fd.append('upload', obj.file);
					// 	fd.append('type', 'Images');
					// 	fd.append('responseType', 'json');
					// 	xhr.send(fd);
					// }




					
				}
			});

			// 插件按钮
			editor.ui.addButton('uploads', {
				label: '上传文件',
				command: 'uploads',
				toolbar: 'insert',
				icon: this.path + 'icons/uploads.png'
			});

			// 插件窗口
			// CKEDITOR.dialog.add('uploads', this.path + 'dialogs/uploads.js');
		}
	});
})();

这个js 主要就是添加一个按钮 点击这个按钮 就调用一个回调方法 这个回调方法 又调用了组件里面的方法 editor.config.uploads().uploadFun(editor, uio)

然后在看看组件怎么写的

<template>
    <div v-loading="loading">
        <!-- <ckeditor v-model="editorData" :config="editorConfig"></ckeditor> -->
        <textarea :id="id" name="content"></textarea>
    </div>
</template>
<script>
/* eslint-disable */
// import CKEditor from 'ckeditor4-vue'
import { uploadUrl } from '@/api/index'
import axios from 'axios'
export default {
    // components:{
    //     ckeditor: CKEditor.component
    // },
    // data () {
    //     return {
    //         editorData: '<p>输入你要输入的内容.</p>',
    //         editorConfig: {
    //             autoGrow_bottomSpace: 60,
    //             autoGrow_minHeight: 400,
    //             autoGrow_maxHeight: 800,
    //             toolbarGroups : [
    //                 { name: 'document', groups: [ 'mode', 'document', 'doctools' ] },
    //                 { name: 'clipboard', groups: [ 'clipboard', 'undo' ] },
    //                 { name: 'editing', groups: [ 'find', 'selection', 'spellchecker', 'editing' ] },
    //                 { name: 'forms', groups: [ 'forms' ] },
    //                 '/',
    //                 { name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] },
    //                 { name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align', 'bidi', 'paragraph' ] },
    //                 { name: 'links', groups: [ 'links' ] },
    //                 { name: 'insert', groups: [ 'insert' ] },
    //                 '/',
    //                 { name: 'styles', groups: [ 'styles' ] },
    //                 { name: 'colors', groups: [ 'colors' ] },
    //                 { name: 'tools', groups: [ 'tools' ] },
    //                 { name: 'others', groups: [ 'others' ] },
    //                 { name: 'about', groups: [ 'about' ] }
    //             ]
    //         }
    //     }
    // },
    props: ["content"],//从父组件转递的内容
    mounted: function() {
        const self = this;
        // 渲染编辑器
        uploadUrl().then(res=>{
            this.uploadFileUrl = res;
            this.loading = false
            self.ckeditor = window.CKEDITOR.replace('content', {
                height:'600px' , 
                removeDialogTabs: 'image:advanced;image:Link',
                image_previewText: ' ',
                uploads: function () {
                    return {
                        // url: res,
                        // 自定义的请求头
                        // header: {
                        //     token: '123456'
                        // },
                        // 自定义的请求体
                        // body: {
                        //     size: 10
                        // },
                        /* 为保证确认后正确回显
                        * 服务器上传请求返回值默认为{code:000,url:'http://***'},默认值为url
                        * 如果返回体为{code:000,data:{url:'http://***'}},请设置图片路径为 resUrl:'data.url'
                        * 错误返回{code:401,error:'权限不足.'}
                        */
                        // resUrl: 'url',
                        // 是否开启多文件上传,默认false,不开启
                        // multiple: false,
                        // // 回显图片/链接 默认回显图片 true
                        // isImg: true,
                        uploadFun: (editor, uio) => {
                            // 自定义回调上传方法
                            uio.forEach(file => {
                                self.uploadImg(file, editor)
                            });  
                        }
                    }
                }

            });//定义编辑器的高度
            // 设置初始内容
            self.ckeditor.setData(self.content);
            // 监听内容变更事件
            self.ckeditor.on("change", function() {
                self.$emit("sendContnet", self.ckeditor.getData());
            });
        })
    },
    data: function() {
        return {
            loading: true,
            uploadFileUrl: '',
            id: parseInt(Math.random() * 10000).toString(),
            ckeditor: null
        };
    },
    watch: {
        // 监听prop的变化,更新ckeditor中的值
        content: function() {
            if (this.content !== this.ckeditor.getData()) {
                this.ckeditor.setData(this.content);
            }
        }
    },
    methods:{
        async uploadImg (files, editor) {
                let file = files.file
                let size = files.file.size
                // let maxLength = 1024 * 1024 * 6;//最大2M
                // if (size > maxLength) {
                //     this.$message.error('文件不能超过2M,请压缩后再上传!');
                //     return false;
                // }
                let formData = new FormData();
                formData.append('img', file);
                this.loading = true
                axios.post(this.uploadFileUrl, formData).then((res) => {
                    this.loading = false
                    if(res.data.code === 200){
                        editor.insertElement(CKEDITOR.dom.element.createFromHtml('<p><img src="' + res.data.url + '" /></p>'));
                    } 
                })
        },
    }
}
</script>

然后在你需要使用的地方引用这个组件就好了 不会联系我 微信:zhouguang199519