中文文档:TinyMCE中文文档中文手册
一、安装
yarn add "@tinymce/tinymce-vue@^5" // yarn
npm install "@tinymce/tinymce-vue@^5" // npm
二、下载汉化包
https://www.tiny.cloud/get-tiny/language-packages/
zh_CN.js
将下载后的压缩包解压到assets\ public文件夹下
三、创建一个vue文件
<template>
<editor v-model="myValue" :init="init" :disabled="ibDialogVisible" :id="tinymceId" @change="hanlderChange"
ref="refEditor" @blur="blur" ></editor>
</template>
<script setup>
//JS部分
//在js中引入所需的主题和组件
import tinymce from "tinymce/tinymce";
import "tinymce/skins/content/default/content.css";
import Editor from "@tinymce/tinymce-vue";
import "tinymce/themes/silver";
import "tinymce/themes/silver/theme";
import "tinymce/icons/default"; //引入编辑器图标icon,不引入则不显示对应图标
import "tinymce/models/dom"; //
//在TinyMce.vue中接着引入相关插件
import "tinymce/icons/default/icons";
import "tinymce/plugins/image" // 插入上传图片插件
// import "tinymce/plugins/media" // 插入视频插件
import "tinymce/plugins/table"; // 插入表格插件
import "tinymce/plugins/lists"; // 列表插件
import "tinymce/plugins/wordcount"; // 字数统计插件
import "tinymce/plugins/code"; // 源码
// import "tinymce/plugins/fullscreen" //全屏
import langUtl from "@/api/utils/langUtl.js";
//接下来定义编辑器所需要的插件数据
import { reactive, ref } from "vue";
import {
onMounted,
defineEmits,
watch,
onBeforeMount,
} from "@vue/runtime-core";
import axios from "axios";
// import { updateImg } from '@/api/order/order'
const emits = defineEmits(["getContent"]);
const props = defineProps({
replayClick: {
type: Boolean,
default: false,
},
value: {
// type: String,
default: () => {
return "";
},
// default:""
},
baseUrl: {
// type: String,
default: "",
},
disabled: {
// type: Boolean,
default: false,
},
plugins: {
// type: [String, Array],
default: "lists table image",
// default: "table lists link image imagetools media code codesample anchor emoticons wordcount preview fullpage fullscreen",
}, //必填
toolbar: {
// type: [String, Array],
default:
"codesample fontfamily fontsize fontsizeselect bold italic underline alignleft aligncenter alignright alignjustify | undo redo | forecolor backcolor | bullist numlist outdent indent | lists link table code | removeformat | empty ",
}, //必填
height: {
default: 300,
},
width: {
default: 800,
},
});
var refEditor = ref();
const languageDic = {
en:{
language:'en',
language_url:''
},
ch:{
language:"zh-Hans",
language_url:'/tinymce/langs/zh-Hans.js'
},
lang3:{
language:"fr_FR",//法语
language_url:'/tinymce/langs/fr_FR.js'
},
lang4:{
language:"es",//西班牙语
language_url:'/tinymce/langs/es.js'
},
lang5:{
language:"ru",//俄语
language_url:'/tinymce/langs/ru.js'
}
}
function focusEditor() {
refEditor.value.focus()
}
defineExpose({
focusEditor,
});
//用于接收外部传递进来的富文本
const myValue = ref();
const tinymceId = ref(
"vue-tinymce-" + +new Date() + ((Math.random() * 1000).toFixed(0) + "")
);
const lang = sessionStorage.getItem('lang')
//定义一个对象 init初始化
const init = reactive({
selector: "#" + tinymceId.value, //富文本编辑器的id,
language_url: languageDic[lang].language_url, // 语言包的路径,具体路径看自己的项目,文档后面附上中文js文件
icons: 'default',
language: languageDic[lang].language, // 配置语言包
skin_url: "/tinymce/skins/ui/oxide", // skin路径,具体路径看自己的项目
promotion: false,
statusbar: false,
height: props.height, //编辑器高度
width: props.width,
branding: false, //是否禁用“Powered by TinyMCE”
menubar: true, //顶部菜单栏显示
image_dimensions: true, //图片宽高属性
plugins: props.plugins, //这里的数据是在props里面就定义好了的
toolbar: props.toolbar, //这里的数据是在props里面就定义好了的
// font_formats:
// "Arial=arial,helvetica,sans-serif; 宋体=SimSun; 微软雅黑=Microsoft Yahei; Impact=impact,chicago;", //字体
fontsize_formats: '11px 12px 14px 16px 18px 24px 36px 48px',
font_formats: "微软雅黑=Microsoft YaHei,Helvetica Neue,PingFang SC,sans-serif;苹果苹方=PingFang SC,Microsoft YaHei,sans-serif;宋体=simsun,serif",
// fontsize_formats: "11px 12px 14px 16px 18px 24px 36px 48px 64px 72px", //文字大小
// fontsize_formats: "8pt 10pt 12pt 14pt 18pt 24pt 36pt",
// paste_convert_word_fake_lists: false, // 插入word文档需要该属性
paste_webkit_styles: "all",
paste_merge_formats: true,
nonbreaking_force_tab: false,
paste_auto_cleanup_on_paste: false,
file_picker_types: "file",
content_css: "/tinymce/skins/content/default/content.css", //以css文件方式自定义可编辑区域的css样式,css文件需自己创建并引入
menubar: false,
// auto_focus: true,
setup: function (editor) {
editor.on("init", function () {
this.getDoc().body.innerHTML = myValue.value;
});
refEditor.value = editor
// 注册清空内容按钮 自定义操作按钮
editor.ui.registry.addButton('empty', {
tooltip: langUtl.t('清空内容'),
icon: 'remove',
onAction: () => {
// _this.content = ''
editor.setContent('')
}
})
},
});
//监听外部传递进来的的数据变化
watch(
() => props.value,
() => {
console.log("监听props.value", props.value);
myValue.value = props.value;
// emits("getContent", myValue.value);
},
{
deep: true,
immediate: true,
}
);
watch(
() => props.replayClick,
(newVal) => {
if (newVal) {
console.log("refEditor", refEditor.value);
// refEditor.value.editorManager.get('tinymceId').focus();
}
},
{
deep: true,
immediate: true,
}
);
//在onMounted中初始化编辑器
onMounted(() => {
tinymce.init({});
});
function hanlderChange() {
console.log("输入时", myValue.value);
emits("getContent", myValue.value);
}
function blur(){
console.log("失焦了");
emits("handleBlur", myValue.value);
}
</script>
<style scoped>
textarea {
display: none;
}
</style>
问题:
1、项目中多个地方使用,注意设置随机id,可参考:
const tinymceId = ref(
"vue-tinymce-" + +new Date() + ((Math.random() * 1000).toFixed(0) + "")
);
2、自定义操作按钮 以及事件:
根据自己的需求,配置需要用到的菜单功能,支持自定义操作按钮
在定义的init初始化配置对象setup函数 注册需要用的功能按钮以及事件
setup: function (editor) {
editor.on("init", function () {
this.getDoc().body.innerHTML = myValue.value;
});
refEditor.value = editor
// 注册清空内容按钮 自定义操作按钮
editor.ui.registry.addButton('empty', {
tooltip: langUtl.t('清空内容'),
icon: 'remove',
onAction: () => {
// _this.content = ''
editor.setContent('')
}
})
},
3、富文本编辑器嵌入到弹窗dialog中,操作栏点击无效:
将富文本编辑器放到dialog弹窗中,发现操作栏点击没有反应,调试发现弹窗的遮罩层z-index比富文本编辑器的操作栏的高,找到编辑主题,然后在主题文件中的 skin.min.css 中查找 z-index ,将层级全部扩大十倍、百倍等,使 tinymce 编辑栏的层级全部大于 dialog 的层级即可,这样编辑栏就会正常显示以及正常点击操作。
4、在同一界面 多个富文本编辑器 设置部分编辑器为只读
在同一界面,多个富文本编辑器,设置部分编辑器为只读不可编辑的
tinyMCE.get(id).mode.set("readonly");
<TEditor
v-if="ibEditorShow"
ref="editorTwo"
:value="ioFormData.content_text"
:disabled="ibDialogVisible"
@getContent="getContent"
height="300"
width="862"
aria-readonly="true"
class="teditor1"
/>
<TEditor
v-if="ibEditorShow"
ref="editorOne"
:value="ioFormData.review_content"
:disabled="ibDialogVisible"
@getContent="getContent1"
height="300"
width="862"
class="teditor2"
/>
import TEditor from "@/components/ctrRichTextExt.vue"; //引入富文本组件
var teditor1 = document.getElementsByClassName("teditor1");
var teditor2 = document.getElementsByClassName("teditor2");
// 在拿到 teditor1 teditor2 实例后 再进行设置readonly属性
tinyMCE.get(teditor1[0].id).mode.set("readonly");
tinyMCE.get(teditor2[0].id).mode.set("readonly");
以上为我在项目中使用富文本编辑器Tinymce遇到的一些问题以及我的解决方案