目录
- 一、下载并重新组织tinymce结构
- 二、使用
- 三、遇到的坑
一、下载并重新组织tinymce结构
- 下载
npm install tinymce@^7
or
yarn add tinymce@^7
-
重构目录
在node_moudles里找到tinymce文件夹,把里面文件拷贝一份放到public下,如下:
-- public
plugins
tinymce
icons
models
plugins
skins
themes
不这么做的话 只引入tinymce是没有办法自动引入正确的插件路径,控制台会报一堆错:
Uncaught SyntaxError: Unexpected token '<' (at theme.js:1:1)
Uncaught SyntaxError: Unexpected token '<' (at model.js:1:1)
Uncaught SyntaxError: Unexpected token '<' (at icons.js:1:1)
- language 、 editimage插件引入方法
此时,还缺少language和editimage插件如果需要的话,可以从这里找language。
editimage的话,因为是收费的,所以我在他们官网上针对editimage插件使用Demo进行爬取
然后editimage放入tinymce自己的组件里,仿照他的样子自己搞
// index.js
require('./plugin.js');
// plugin.js
...
此时还会报一个错,就是editimage下的language找不到,那就把上面的文件拿过来放到对应的位置即可,所以你会看到我的文件里还多了一个language。
到此为止准备阶段算是完了。
二、使用
此时可以直接引用tinymce,自动引入会根据base_url进行查找,我们刚才把准备工作做好了,可以直接设置
<template>
<div style="height:100vh">
<textarea id="tinymce"></textarea>
</div>
</template>
<script>
import tinymce from "tinymce";
export default{
data(){
return{
editor:null,
}
},
mounted(){
tinymce.init({
selector: "#tinymce",
license_key: 'gpl',
height:'100%',
base_url:'plugins/tinymce/',// 设置资源根路径
language: 'zh_CN', // 设置语言为中文
language_url: 'plugins/tinymce/langs/zh_CN.js', // 这里的地址指向 public 目录下的路径
plugins: 'quickbars preview importcss image editimage searchreplace autolink autosave save directionality code visualblocks visualchars fullscreen link media codesample table charmap pagebreak nonbreaking anchor insertdatetime advlist lists wordcount help charmap emoticons accordion',
toolbar: " undo redo | shot copy paste | accordion accordionremove | fontselect styleselect fontsize | bold italic underline strikethrough | align numlist bullist | link image | table media | lineheight outdent indent| forecolor backcolor removeformat | charmap emoticons | code fullscreen preview | save print | pagebreak anchor codesample | ltr rtl ",
editimage_toolbar: 'rotateleft rotateright | flipv fliph | editimage imageoptions',
fontsize_formats: '12px 14px 16px 18px 20px 22px 24px 26px 36px 48px 56px', // 工具栏自定义字体大小选项
font_formats: "微软雅黑='微软雅黑'; 宋体='宋体'; 黑体='黑体'; 仿宋='仿宋'; 楷体='楷体'; 隶书='隶书'; 幼圆='幼圆'; 方正舒体='方正舒体'; 方正姚体='方正姚体'; 等线='等线'; 华文彩云='华文彩云'; 华文仿宋='华文仿宋'; 华文行楷='华文行楷'; 华文楷体='华文楷体'; 华文隶书='华文隶书'; Andale Mono=andale mono,times; Arial=arial; Arial Black=arial black;avant garde; Book Antiqua=book antiqua;palatino; Comic Sans MS=comic sans ms; Courier New=courier new;courier; Georgia=georgia; Helvetica=helvetica; Impact=impact;chicago; Symbol=symbol; Tahoma=tahoma;arial; sans-serif; Terminal=terminal,monaco; Times New Roman=times new roman,times; Trebuchet MS=trebuchet ms; Verdana=verdana;geneva; Webdings=webdings; Wingdings=wingdings", // 工具栏自定义字体选项
branding: false, // 去掉编辑器右下角的广告
menubar: false,
paste_data_images: true,
highlight_on_focus: false,// 边框高亮
contextmenu: "",//右键菜单
content_style:"",//纯css代码,控制iframe内的文档
toolbar_location: "top",
editimage_toolbar: ' customAIDuiHuaButton |rotateleft rotateright | flipv fliph | editimage imageoptions',//选择图片时的toolbar
quickbars_insert_toolbar: false,//插入时是否展示快捷键
quickbars_selection_toolbar: 'customAIDuiHuaButton customAIButton bold italic underline fontsize forecolor numlist blockquote ',选择时展示的快捷键
save_onsavecallback: () => {//保存时才会有的钩子函数,保存回调
// 解决保存时,触发的找不到form表单的提示
console.log('Saved');
_this.$emit('save');
},
init_instance_callback:(editor)=>{//初始化回调
this.editor=editor;
// 设置初始值
let content = '中国万岁,共产党万岁!!!';
editor.setContent(content, {
format: 'html'
})
},
setup: (editor) => {
// 编辑器监听内容改变,和input的change事件不同,官网上解释是除了其他操作外,输入文字不会立即触发,而是只有焦点不在编辑器上是才会触发
editor.on('change',(e)=>{
this.$emit("update:value", editor.getContent({format:'html'}));
})
// 注册一个图标
editor.ui.registry.addIcon('shot-cut', '<svg t="1733897029101" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5750" width="24" height="24"><path d="M715.98 634.01h80.07V308.02c0-21.61-7.94-40.35-23.83-56.24-15.89-15.89-34.63-23.83-56.24-23.83H389.99v80.07h325.99v325.99z m-407.96 81.97V64h-80.07v163.95H64v80.07h163.95v407.97c0 21.6 7.94 40.35 23.83 56.24 15.89 15.89 34.63 23.83 56.24 23.83h407.97V960h80.07V796.05H960v-80.07H308.02z" p-id="5751"></path></svg>');
editor.ui.registry.addButton('shot', {
icon:'shot-cut',//使用这个图标
tooltip:'截屏',
onAction: (_) => {
// TO-DO
}
});
editor.ui.registry.addIcon('ai', '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n' + '<path fill-rule="evenodd" clip-rule="evenodd" d="M5 3C3.34315 3 2 4.34315 2 6V18C2 19.6569 3.34315 21 5 21H19C20.6569 21 22 19.6569 22 18V6C22 4.34315 20.6569 3 19 3H5ZM11.8038 14.4512L12.2652 15.6641C12.3268 15.8135 12.3993 15.9871 12.4828 16.1849C12.5707 16.3782 12.652 16.5233 12.7267 16.6199C12.8014 16.7122 12.8937 16.7847 13.0035 16.8375C13.1134 16.8946 13.2452 16.9232 13.399 16.9232C13.6627 16.9232 13.8868 16.8309 14.0714 16.6463C14.2604 16.4573 14.3548 16.2508 14.3548 16.0267C14.3548 15.8113 14.256 15.4664 14.0582 14.9918L11.5336 8.75593C11.4149 8.44392 11.316 8.19563 11.2369 8.01105C11.1622 7.82209 11.0677 7.64631 10.9535 7.48371C10.8436 7.32111 10.6964 7.18928 10.5118 7.0882C10.3316 6.98273 10.1053 6.93 9.83287 6.93C9.5648 6.93 9.33849 6.98273 9.15392 7.0882C8.97374 7.18928 8.82652 7.32331 8.71227 7.4903C8.6024 7.6573 8.49693 7.86823 8.39586 8.12312C8.29918 8.3736 8.21568 8.58894 8.14537 8.76911L5.67345 15.0445C5.57237 15.295 5.49986 15.4905 5.45592 15.6312C5.41197 15.7718 5.39 15.908 5.39 16.0399C5.39 16.2684 5.48448 16.4727 5.67345 16.6529C5.86241 16.8331 6.07994 16.9232 6.32603 16.9232C6.61607 16.9232 6.82481 16.8397 6.95226 16.6727C7.0797 16.5013 7.23351 16.1739 7.41368 15.6905L7.87511 14.4512H11.8038ZM9.81969 8.99323L11.2765 12.9813H8.38927L9.81969 8.99323ZM15.3775 8.11652V15.73C15.3775 16.1256 15.4676 16.4244 15.6478 16.6265C15.8324 16.8243 16.0653 16.9232 16.3465 16.9232C16.641 16.9232 16.8783 16.8243 17.0585 16.6265C17.243 16.4288 17.3353 16.13 17.3353 15.73V8.11652C17.3353 7.71662 17.243 7.41999 17.0585 7.22663C16.8783 7.02888 16.641 6.93 16.3465 6.93C16.0609 6.93 15.828 7.02888 15.6478 7.22663C15.4676 7.42439 15.3775 7.72102 15.3775 8.11652Z" fill="rgba(180, 104, 106, 1.000)"/>\n' +'</svg>');
editor.ui.registry.addButton('customAIDuiHuaButton', {
icon: 'ai',
text: '小Q对话',
onAction:()=>{
// TO-DO
}
});
editor.ui.registry.addMenuButton('customAIButton', {
icon: 'ai',
text: 'AI工具',
fetch:(callback)=>{
const items = [
{
type: 'menuitem',
text: '续写',
onAction: (_) =>{
// TO-DO
}
},
{
type: 'menuitem',
text: '续写',
getSubmenuItems: () => [
{
type: 'menuitem',
text: '轻松诙谐',
onAction: (_) => {
// TO-DO
}
},
{
type: 'menuitem',
text: '商务正式',
onAction: (_) => {
// TO-DO
}
}
]
}
];
callback(items)
}
});
}
})
}
}
</script>
三、遇到的坑
- 如果遇到了tab切换,tinymce需要手动销毁,否则无法使用,所以在初始化的时候需要进行remove。
mounted() {
this.$nextTick(v=>{
this.render();
})
},
methods:{
render(){
tinymce.remove('#'+this.tinymceId);
tinymce.init(this.options)
},
}
- save的时候报错,form表单找不到,解决办法
data(){
return {
options:{
//...
save_onsavecallback: () => {//保存时才会有的钩子函数,保存回调
// 解决保存时,触发的找不到form表单的提示
console.log('Saved');
_this.$emit('save');
},
//...
}
}
}