中文文档
TinyMce在4.0以后就不支持Vue2.0了
1. 安装依赖
yarn add tinymce || npm install tinymce -Syarn add @tinymce/tinymce-vue || npm install @tinymce/tinymce-vue -S
2. 创建组件
在 components
下创建 Tinymce.vue
组件
<template><div class="app-container"><editor :id="selector" v-model="tinymceHtml" :init="init" :disabled="disabled"></editor></div>
</template>
<script setup>
import { ref, onMounted, watch, toRef } from 'vue';
import tinymce from 'tinymce/tinymce';
// import "tinymce/models/dom"; // 特别注意 tinymce 6.0.0 版本之后必须引入,否则不显示
import 'tinymce/themes/silver/theme';
import api from '@/api';
import Editor from '@tinymce/tinymce-vue'; // 引入组件// 以下都是富文本插件
import 'tinymce/icons/default';
import 'tinymce/plugins/link';
import 'tinymce/plugins/code';
import 'tinymce/plugins/table';
import 'tinymce/plugins/lists';
import 'tinymce/plugins/wordcount';
import 'tinymce/plugins/hr'; //水平分割线
import 'tinymce/plugins/emoticons';
import 'tinymce/plugins/textcolor';
import 'tinymce/plugins/preview'; //预览
import 'tinymce/plugins/image';
import 'tinymce/plugins/media';
import 'tinymce/plugins/paste';
// 以上所有的样式在 node_modules 下面 tinymce 里面的 plugins 都能找到。const emits = defineEmits(['getEditor']);
const props = defineProps({value: {type: String,default: ''},imageShow: {type: Boolean,default: true},type: {type: Number,default: 0},selector: {type: String,default: 'tinymce'},disabled: {type: Boolean,default: false}
});
const dataValue = toRef(props, 'value');
let tinymceHtml = ref('');
const init = {selector: props.selector,language_url: '/tinymce/langs/zh_CN.js', // 引入语言包(该语言包在public下,注意文件名称)language: 'zh_CN', // 这里名称根据 zh_CN.js 里面写的名称而定skin_url: '/tinymce/skins/ui/oxide', // 这里引入的样式height: 400, // 限制高度plugins: `link lists code table textcolor wordcount emoticons hr image media preview paste`, // 富文本插件paste_data_images: true, // 禁止从剪贴板粘贴图片lineheight_formats: '0.5 0.8 1 1.2 1.5 1.75 2 2.5 3 4 5',fontsize_formats: '12px 14px 16px 18px 20px 22px 24px 26px 30px 36px 40px 45px 50px',toolbar1: `fontsizeselect bold italic underline strikethrough | media image| table |lineheight | forecolor| backcolor |emoticons hr| alignleft aligncenter| alignright alignjustify | bullist numlist |outdent indent blockquote | undo redo | lists link unlink code | preview | removeformat | paste`,branding: false, // //是否禁用“Powered by TinyMCE”placeholder: '在这里输入文字',style_formats: [{ title: 'Custom Padding', inline: 'p', styles: { padding: '0 10px' } }],menubar: false, //顶部菜单栏显示media_live_embeds: true,file_picker_types: 'media', // 上传类型 视频media_alt_source: false, //显示隐藏资源备用地址输入框media_filter_html: false, // 视频上传代码过滤image_dimensions: false, // 隐藏图片尺寸media_dimensions: false, //显示隐藏宽高尺寸输入框emoticons_database_url: '/tinymce/emoticons/js/emojis.js',// paste_convert_word_fake_lists: false, // 插入word文档需要该属性content_css: '/tinymce/skins/content/default/content.css', //以css文件方式自定义可编辑区域的css样式,css文件需自己创建并引入images_upload_handler: async (blobInfo, success) => { // 自定义函数代替TinyMCE来处理上传操作const formData = new FormData();formData.append('file', blobInfo.blob());const res = await api.upload(blobInfo.blob()); // 请求接口success(res.url);},file_picker_callback: function (callback, value, meta) { // 文件上传if (meta.filetype === 'media') {const input = document.createElement('input');input.setAttribute('type', 'file');input.setAttribute('accept', 'video/*');input.onchange = async function () {const file = this.files[0];const formData = new FormData();formData.append('file', file);const res = await api.upload(formData); // 请求接口callback(res.url);};input.click();}},setup: function (editor) { // 初始化前执行console.log("ID为: " + editor.id + " 的编辑器即将初始化.");},init_instance_callback : function(editor) { // 初始化结束后执行console.log("ID为: " + editor.id + " 的编辑器已初始化完成.");}
};
if (dataValue.value) {tinymceHtml.value = dataValue.value;
}watch(() => tinymceHtml,(newType, oldType) => {emits('getEditor', newType['_value']);},{ deep: true }
);
watch(() => dataValue,(newType, oldType) => {console.log(newType);tinymceHtml.value = newType.value || '';},{ deep: true }
);onMounted(() => {tinymce.init({}); // 初始化富文本
});
</script><style></style>
3. 使用组件
<template><div class="tinymce-box"><Tinymce :value="information" @getEditor="getEditor" :disabled="disabled" /></div>
</template><script setup>
import Tinymce from "@/components/Tinymce.vue";const information = ref('');
const disabled = false;
const getEditor = value => {information.value = value;
};
</script><style scoped>
.tinymce-box {width: 100%;
}
</style>