富文本编辑器Tinymce vue3项目使用以及遇到的问题

官方文档:https://www.tiny.cloud/

中文文档: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遇到的一些问题以及我的解决方案

 

  • 11
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值