后台Springboot,tinymce版本5.5.1,只贴出关键代码,有代码缺失情况请留言提醒,蟹蟹蟹蟹。
npm install tinymce -S
npm install @tinymce/tinymce-vue -S
下载后,在node_modules中找到tinymce文件夹,全部拷贝到项目里,我放在了src下assets中。
在需要引入得页面引入,以下是我的路径,需要修改成自己的
import tinymce from '../../assets/tinymce/tinymce'
import '../../assets/tinymce/themes/silver/theme'
import '../../assets/tinymce/skins/ui/oxide/content.css'
import '../../assets/tinymce/skins/ui/oxide/skin.css'
import Editor from "@tinymce/tinymce-vue"
// 中文语言包
import '../../assets/tinymce/zh_CN.js'
// 字体
import '../../assets/tinymce/icons/default/icons'
// 插件
import '../../assets/tinymce/plugins/image'
import '../../assets/tinymce/plugins/media'
import '../../assets/tinymce/plugins/table'
import '../../assets/tinymce/plugins/lists'
import '../../assets/tinymce/plugins/contextmenu'
import '../../assets/tinymce/plugins/wordcount'
import '../../assets/tinymce/plugins/colorpicker'
import '../../assets/tinymce/plugins/textcolor'
import '../../assets/tinymce/plugins/code'
import '../../assets/tinymce/plugins/link'
import '../../assets/tinymce/plugins/hr'
import '../../assets/tinymce/plugins/imagetools'
中文语言包下载
https://download.csdn.net/download/lmq2582609/12927198
在页面组件中引入
components: {
Editor
},
<editor id='tinymce' v-model='postsContent' :init='init'></editor>
数据绑定
data() {
return {
// 文章内容
postsContent: '',
// 初始化参数
//富文本编辑器初始化配置
init: {
language: 'zh_CN',
plugins: 'link lists image media code table hr imagetools colorpicker textcolor wordcount fullscreen contextmenu',
toolbar: 'undo redo | bold italic underline strikethrough | fontsizeselect | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist | outdent indent blockquote | image media | link unlink | removeformat | fullscreen',
branding: false,
height: 380,
paste_data_images: true, // 粘贴时能图片自动上传
min_height: 380,
max_height: 380,
// 图片本地上传方法 点击上传后执行的事件
images_upload_handler: (blobInfo, success, failure) => {
var xhr, formData;
xhr = new XMLHttpRequest();
xhr.withCredentials = false;
//打开对象 - 上传地址
xhr.open('POST', this.uploadURL);
// 设置请求头,携带token
xhr.setRequestHeader('Authorization', window.sessionStorage.getItem('token'))
xhr.onload = function () {
var json;
if (xhr.status != 200) {
failure('HTTP Error: ' + xhr.status);
return;
}
json = JSON.parse(xhr.responseText);
if (!json || json.code != '200' || typeof json.data.src != 'string') {
failure('Invalid JSON: ' + xhr.responseText);
return;
}
//success成功回显图片
success(json.data.src);
};
formData = new FormData();
formData.append('file', blobInfo.blob(), blobInfo.filename());
xhr.send(formData);
},
//文件上传
file_picker_callback: (cb, value, meta) => {
const _this = this
//media - 视频
if (meta.filetype == 'media') {
//创建一个隐藏的type=file的文件选择input
let input = document.createElement('input');
input.setAttribute('type', 'file');
input.onchange = function(){
//只选取第一个文件。如果要选取全部,后面注意做修改
let file = this.files[0];
let xhr, formData;
xhr = new XMLHttpRequest();
//自定义文件上传
xhr.open('POST', _this.uploadURL);
// 设置请求头,携带token
xhr.setRequestHeader('Authorization', window.sessionStorage.getItem('token'))
xhr.withCredentials = true;
xhr.onerror = function () {
_this.msg.error('HTTP 错误: ' + xhr.status)
return;
};
xhr.onload = function () {
let json;
if (xhr.status != 200) {
_this.msg.error('HTTP 错误: ' + xhr.status)
return;
}
json = JSON.parse(xhr.responseText);
if (!json || json.code != '200' || typeof json.data.src != 'string') {
_this.msg.error('HTTP 错误,返回值: ' + xhr.responseText)
return;
}
//接口返回的文件保存地址
let mediaLocation = json.data.src;
//cb()回调函数,将mediaLocation显示在弹框输入框中
cb(mediaLocation, { title: file.name });
};
formData = new FormData();
//假设接口接收参数为file,值为选中的文件
formData.append('file', file);
//正式使用将下面被注释的内容恢复
xhr.send(formData);
}
//触发点击
input.click();
}
},
media_url_resolver: (data, resolve)=> {
try {
let videoUri = encodeURI(data.url);
let embedHtml = `<p>
<span
class="mce-object mce-object-video"
data-mce-selected="1"
data-mce-object="video"
data-mce-p-width="100%"
data-mce-p-height="auto"
data-mce-p-controls="controls"
data-mce-p-controlslist="nodownload"
data-mce-p-allowfullscreen="true"
data-mce-p-src=${videoUri} >
<video src=${data.url} width="100%" height="auto" controls="controls" controlslist="nodownload">
</video>
</span>
</p>
<p style="text-align: left;"></p>`;
resolve({ html: embedHtml });
} catch (e) {
resolve({ html: "" });
}
}
},
}
}
初始化
// 在mounted中执行初始化
mounted() {
// 初始化富文本编辑器
tinymce.init({})
},
遇到的最大的问题,就是报 ‘<’ 符号问题。原因就是引入路径不对,一个一个路径仔细排查就行了。
网上很多在init初始化参数中写了language_url和skin_url,我的tinymce版本是5.5.1,写了也不好使,最后直接引入css就好使了。vue用的不是很6,都是现用现查文档。。。