在 Vue 项目中引入 tinymce 富文本编辑器 前端、若依框架使用tinymce,tinymce上传本地图片
转自:https://my.oschina.net/songms/blog/3092858https://blog.csdn.net/chipang7687/article/details/100724745一、总结1.各个编辑器之间的较量UEditor:百度前端的开源项目,功能强大,基于jQuery,但已经没有再维护,而且限定了后端代码,修改起来比较费劲bootstrap...
·
RuoYi-Vue 前端分离版 集成 富文本编辑(TinyMce) - 沙漏笔记
vue富文本编译器tinymce_若依集成 tinymce-CSDN博客
Tinymce的使用,下载包到本地方式_tinymce下载-CSDN博客
安装
1. npm install tinymce@5.10.3 -S
一定要加版本号!!!有一次写成npm install tinymce,结果出来的编辑器的界面好时髦,居然有惊喜。结果上传图片的时候,提示我Cannot read properties of undefined (reading 'then')。然后我去看了tinymce.min.js的时候,看到了版本号居然是6.0.1,而当时api文档才到5,现在有6了。
6版本的上传图片要写成images_upload_handler: (blobInfo, progress) => new Promise((resolve, reject) => {})
2. npm install @tinymce/tinymce-vue@3.2.6 -S
vue2的话,不要用tinymce-vue@4+
- 从node_modules/tinymce中复制tinymce文件夹,放在public下
- 完成后的目录
3、 下载中文汉化包,复制到public/tinymce下,中文下载地址 http://tinymce.ax-z.cn/static/tiny/langs/zh_CN.js,将下载的汉化包放到langs文件夹下
4.在src/components中新建文件夹tinymce
5.在tinymce新建文件index.vue
6.组件代码
index.vue👇
<template>
<div class="tinymce-box">
<editor v-model="contentValue" :init="init" :disabled="disabled" @click="onClick">
</editor>
</div>
</template>
<script>
// 文档 http://tinymce.ax-z.cn/
// 引入组件
import tinymce from 'tinymce/tinymce' // tinymce默认hidden,不引入不显示
import Editor from '@tinymce/tinymce-vue'
// 引入富文本编辑器主题的js和css
import 'tinymce/skins/content/default/content.css'
import 'tinymce/themes/silver/theme.min.js'
import 'tinymce/icons/default/icons' // 解决了icons.js 报错Unexpected token '<'
// 编辑器插件plugins
// 更多插件参考:https://www.tiny.cloud/docs/plugins/
import 'tinymce/plugins/image' // 插入上传图片插件
import 'tinymce/plugins/media' // 插入视频插件
import 'tinymce/plugins/table' // 插入表格插件
import 'tinymce/plugins/lists' // 列表插件
import 'tinymce/plugins/wordcount' // 字数统计插件
import 'tinymce/plugins/link'
import 'tinymce/plugins/code'
import 'tinymce/plugins/preview'
import 'tinymce/plugins/fullscreen'
import 'tinymce/plugins/help'
export default {
components: {
Editor
},
name: 'Tinymce',
props: {
//内容
value: {
type: String,
default: '',
},
baseUrl: {
type: String,
default: window.location.origin ? window.location.origin : ''
},
//是否禁用
disabled: {
type: Boolean,
default: false,
},
//插件
plugins: {
type: [String, Array],
default: 'advlist autolink link image lists charmap table fullscreen code preview',
},
//工具栏
toolbar: {
type: [String, Array],
default: ()=>['bold italic underline strikethrough | fontsizeselect | formatselect | forecolor backcolor | alignleft aligncenter alignright alignjustify',
'bullist numlist outdent indent blockquote | undo redo | link unlink code lists table image media | removeformat | fullscreen preview'
]
}
},
data() {
return {
init: {
selector: '#tinydemo',
language_url: `${this.baseUrl}/tinymce/langs/zh_CN.js`,
language: 'zh_CN',
skin_url: `${this.baseUrl}/tinymce/skins/ui/oxide`,
// skin_url: 'tinymce/skins/ui/oxide-dark', // 暗色系
convert_urls: false,
height: 300,
// content_css(为编辑区指定css文件),加上就不显示字数统计了
// content_css: `${this.baseUrl}tinymce/skins/content/default/content.css`,
// (指定需加载的插件)
plugins: this.plugins,
toolbar: this.toolbar, // (自定义工具栏)
statusbar: true, // 底部的状态栏
menubar: 'file edit insert view format table tools help', // (1级菜单)最上方的菜单
branding: false, // (隐藏右下角技术支持)水印“Powered by TinyMCE”
// 此处为图片上传处理函数,这个直接用了base64的图片形式上传图片,
images_upload_handler: function(blobInfo, succFun, failFun) {
const file_type = blobInfo.blob().type
const name = blobInfo.filename && blobInfo.filename() || blobInfo.blob().name
//格式校验
const isAccept = file_type === 'image/jpeg' || file_type === 'image/png' || file_type === 'image/GIF' || file_type === 'image/jpg' || file_type === 'image/BMP';
//大小校验
const size = 3
if (blobInfo.blob().size/1024/1024 > size) {
failFun("图片大小请控制在 " + size + "M 以内")
} else if (!isAccept) {
failFun('图片格式错误')
} else {
var xhr, formData;
var file = blobInfo.blob();
xhr = new XMLHttpRequest();
xhr.withCredentials = false;
xhr.open('POST', '上传地址');
xhr.setRequestHeader('Authorization', '自定义');
xhr.onload = function() {
var json;
if (xhr.status != 200) {
failFun('HTTP Error: 上传失败');
return;
}
json = JSON.parse(xhr.responseText);
//
if (!json || json.code != 200) {
failFun('上传失败');
return;
}
succFun(json.data.location);
};
xhr.onerror = function () {
failure(
"Image upload failed due to a XHR Transport error. Code: " +
xhr.status
);
};
formData = new FormData();
formData.append('file', file, file.name );
xhr.send(formData);
}
}
},
contentValue: this.value
}
},
mounted() {
tinymce.init({})
},
methods: {
// 添加相关的事件,可用的事件参照文档=> https://github.com/tinymce/tinymce-vue => All available events
// 需要什么事件可以自己增加
onClick(e) {
this.$emit('onClick', e, tinymce)
},
// 可以添加一些自己的自定义事件,如清空内容
clear() {
this.contentValue = ''
}
},
watch: {
value(newValue) {
this.contentValue = newValue
},
contentValue(newValue) {
this.$emit('input', newValue)
}
}
}
</script>
<style scoped>
</style>
使用
import tinymce from '@/components/tinymce'
components: {
tinymce
}
------------------------
<el-form-item label="内容">
<tinymce v-if="open" v-model="form.content" :disabled="false" ref="tinymce" />
</el-form-item>
tinymce 按照全局引入方式报错:
Unexpected token '<'
解决 public/index.html页面全局引入tinymce.需要这样写👇
<script src="<%= BASE_URL %>tinymce/tinymce.min.js"></script><!-- tinymce -->
富文本框上传本地图片部分
返回信息和接口地址对应
项目后端返回:
具体根据实际接口返回数据修改 api返回的json中,必须包含location字段!!!
xhr.withCredentials = false;
xhr.open("POST", "/prod-api/file/upload");//修改部分
xhr.setRequestHeader("Authorization", "Bearer " + getToken());//修改部分
xhr.onload = function () {
console.log(xhr, "xhrxhrxhr");
var json;
if (xhr.status != 200) {
failFun("HTTP Error: 上传失败");
return;
}
json = JSON.parse(xhr.responseText);
//
if (!json || json.code != 200) {
failFun("上传失败");
return;
}
succFun(json.data.location);//所以此处该加location
};
后端返回注意:api返回的json中,必须包含location字段,比如:{ "location": "folder/sub-folder/new-location.png" }
//json格式
{ "location": "folder/sub-folder/new-location.png" }
更多推荐
所有评论(0)