Vue使用Tinymce 编辑器

目录

一、下载并重新组织tinymce结构

  • 下载
js 复制代码
npm install tinymce@^7
or
yarn add tinymce@^7
  • 重构目录

    在node_moudles里找到tinymce文件夹,把里面文件拷贝一份放到public下,如下:

timeout 复制代码
-- 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自己的组件里,仿照他的样子自己搞
js 复制代码
// index.js
require('./plugin.js');
js 复制代码
// plugin.js
...

此时还会报一个错,就是editimage下的language找不到,那就把上面的文件拿过来放到对应的位置即可,所以你会看到我的文件里还多了一个language。

到此为止准备阶段算是完了。

二、使用

此时可以直接引用tinymce,自动引入会根据base_url进行查找,我们刚才把准备工作做好了,可以直接设置

html 复制代码
<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。
js 复制代码
mounted() {
    this.$nextTick(v=>{
      this.render();
    })
  },
methods:{
    render(){
      tinymce.remove('#'+this.tinymceId);
      tinymce.init(this.options)
    },
}
  • save的时候报错,form表单找不到,解决办法
js 复制代码
data(){
	return {
		options:{
			//...
			save_onsavecallback: () => {//保存时才会有的钩子函数,保存回调
		          // 解决保存时,触发的找不到form表单的提示
		          console.log('Saved');
		          _this.$emit('save');
	        },
			//...
		}
	}
}
相关推荐
沃尔威武16 小时前
调试黑科技:Chrome DevTools时间旅行调试实战
前端·科技·chrome devtools
小锋java123416 小时前
SpringBoot 4 + Spring Security 7 + Vue3 前后端分离项目设计最佳实践
java·vue.js·spring boot
一 乐16 小时前
校园线上招聘|基于springboot + vue校园线上招聘系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·校园线上招聘系统
yuki_uix16 小时前
虚拟 DOM 与 Diff 算法——React 性能优化的底层逻辑
前端·react.js·面试
yuki_uix16 小时前
从输入 URL 到页面显示——浏览器工作原理全解析
前端·面试
LanceJiang16 小时前
从输入 URL 到页面:一个 Vue 项目的“奇幻漂流”
vue.js
weixin_4080996716 小时前
【完整教程】天诺脚本如何调用 OCR 文字识别 API?自动识别屏幕文字实战(附代码)
前端·人工智能·后端·ocr·api·天诺脚本·自动识别文字脚本
吴声子夜歌16 小时前
ES6——Generator函数详解
前端·javascript·es6
吴声子夜歌16 小时前
ES6——Set和Map详解
前端·javascript·es6
码喽7号17 小时前
vue学习四:Axios网络请求
前端·vue.js·学习