背景
原先用的web编辑器是百度前端团队开发的ueditor,百度前端的开源项目,功能强大,基于jQuery,但是此项目已经很久没有再维护,而且限定了后端代码,修改起来比较费劲,最新一次更新还在2016.05.18,因为已经不再维护了,需要大量修改源码,依赖jquery,修改的内容可能污染全局css。
常见富文本编辑器比较
富文本编辑器 | 优点 | 缺点 |
---|---|---|
Tinymce | 支持图片在线处理,插件多,功能强,编辑能力优秀,界面好看。文档好,bug少,无外部依赖,用户评价好,更新频率快 | 低版本IE不兼容 |
ueditor | 插件多,基本满足各种需求,类似贴吧中的回复界面 | 不再维护,图片只能上传到本地服务器,如果需要上传到其他服务器需要改动源码,较为难办。 |
wangEditor | 轻量、简洁、易用 | 没有强大的后台,案例不是很多,也不便于定制化开发 |
bootstrap-wysiwyg | 轻量,好看,使用方便 | 没有开发文档不便于阅读使用,无字体变色,无视频上传功能 。需要一定的浏览器支持,毕竟需要bootstrap。 |
kindEditor | 轻量,好看,使用方便 | 存在图片上传问题,如果上传历史过多,会全部加载,导致浏览器卡,反应慢,而且好久没见更新了 |
CKEditor | 功能强大配置灵活ui漂亮 | 需要指定专门的node以及npm版本,兼容性差 |
最终选择方案
Tinymce
功能强,bug少,无外部依赖,用户评价好,更新频率快。 插件多,tinymce 官方为 vue 项目提供了一个组件 tinymce-vue; 有官方提供的模板选择插件,上传图片插件,字数统计插件,表格插件,添加超链接插件等等我们有可能用到的插件。 是唯一一个从 word 粘贴过来还能保持绝大部分格式的编辑器,可以自己在工具栏加函数方便扩展自用功能。
插件安装
安装tinymce-vue
npm install @tinymce/tinymce-vue -S
下载tinymce
npm install tinymce -S
初始化
引入基本文件
import tinymce from 'tinymce/tinymce'
import Editor from '@tinymce/tinymce-vue'
import 'tinymce/themes/modern/theme'
<editor id="tinymce" v-model="value" :init="init"></editor>
语言包和主题包需要放到项目静态文件夹下
init: {
language_url: '/static/tinymce/langs/zh_CN.js',//语言包的路径
language: 'zh_CN',//语言包(需下载)
skin_url: '/static/tinymce/skins/lightgray',//skin路径
height: 300,//编辑器高度
plugins: ......,//插件
toolbar: ......//工具栏
}
引入插件
import 'tinymce/plugins/image'; // 插入上传图片插件
import 'tinymce/plugins/media';// 插入视频插件
import 'tinymce/plugins/table';// 插入表格插件
import 'tinymce/plugins/lists';// 列表插件
import 'tinymce/plugins/wordcount';// 字数统计插件
import 'tinymce/plugins/template';// 模板插件
import 'tinymce/plugins/lists';// 列表插件
import 'tinymce/plugins/link';// 链接插件
......
工具栏
plugins: 'lists image media table textcolor wordcount contextmenu',
toolbar: 'undo redo | formatselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | lists image media table | removeformat'
......
上传图片功能
需要写在init函数中
images_upload_url: 'service/common/storage',
images_upload_handler: (blobInfo, success, failure) => {
let formData = new FormData();
formData.append('file', blobInfo.blob(), blobInfo.filename());
oc.ajax.post('/service/common/storage', formData, {contentType: false} ).then(res => {
let location=`/service/common/storage?key=${res}`;
success(location);
}
).catch(error =>{
failure(error);
});
# oc.ajax是用的自己封装的ajax组件,这其实就是post请求
},
若需要支持粘贴图片直接上传 则在init里加上
paste_data_images: true
仿照图片上传功能写出附件和视频上传功能
文件上传需要插入link插件和加上link工具
file_picker_types: 'image file media',
file_picker_callback: function(callback, value, meta) {
let input = document.createElement('input');
input.setAttribute('type', 'file');
// 你可以给input加accept属性来限制上传的文件类型
// input.setAttribute('accept', '.jpg,.png');
input.click();
input.onchange = function() {
let file = this.files[0];
let formData = new FormData();
formData.append('file', file, file.name);
oc.ajax.post('/service/common/storage', formData, {contentType: false}).then(res =>{
let location=`/service/common/storage?key=${res}`;
# Provide image and alt text for the image dialog
if (meta.filetype == 'image') {
callback(location, {alt: 'My image'});
}
# Provide file and text for the link dialog
if (meta.filetype == 'file') {
callback(location, {text: 'My file'});
}
# Provide alternative source and posted for the media dialog
if (meta.filetype == 'media') {
callback(location, {title: 'My media'});
};
});
};
}