TinyMce富文本编辑器 在Vue3 vue-vite中使用,遇到的重载和加载空白问题

本文讲述了作者在使用TinyMce富文本编辑器时遇到的两个问题:加载时空白不渲染和路由跳转后页面空白。通过引入正确的文件路径、设置唯一组件ID以及销毁编辑器实例,作者提供了详细的解决步骤和代码示例。
摘要由CSDN通过智能技术生成

这个用来记录我使用TinyMce富文本编辑器时遇到的一些问题

1.加载空白,不渲染问题

2.路由跳转以后,页面空白问题

首先我是看了其他的两篇帖子,最后找到了解决方案

https://juejin.cn/post/6921986236408152077
https://blog.csdn.net/m0_73358221/article/details/129358814#comments_30465890

1.加载空白,不渲染问题

我是使用npm的方式安装的TinyMce。

版本分别是

"dependencies": {
    "@tinymce/tinymce-vue": "^5.1.1",
    "tinymce": "^6.8.2"
}

将安装好的文件复制到public里面

然后在富文本初始化的时候加入一行

skin_url: '../tinymce/skins/ui/oxide',

路径就是复制到public里文件的路径,每个人可能都不一样

2.路由跳转以后,页面空白问题

这个问题的具体原因我也不是很清楚,应该就是销毁了,但是没有完全销毁,所以组件没有进行重新初始化。

解决方法:给组件上一个唯一id

const id = 'vue-tinymce-' + +new Date() + ((Math.random() * 1000).toFixed(0) + '')

下面贴上我的完整代码:

首先是组件页面:TinyMce.vue

<template>
  <textarea :id="id" style="width: 100%"></textarea>
</template>

<script setup>
import tinymce from 'tinymce/tinymce'; //tinymce核心文件
import 'tinymce/models/dom'; // 引入dom模块。从 Tinymce6,开始必须有此模块导入
import 'tinymce/themes/silver'; //默认主题
import 'tinymce/icons/default/icons.min.js'; //引入编辑器图标icon,不引入则不显示对应图标
import '/public/tinymce/langs/zh-Hans'; //引入编辑器语言包
/* 引入编辑器插件
 * 位于 ./node_modules/tinymce/plugins 目录下,版本不同,插件会有所差异。根据自己版本来导入,若不存在的,不能导入,会报错。
 */
import 'tinymce/skins/ui/oxide/skin.min.css'
import 'tinymce/plugins/advlist'; //高级列表
import 'tinymce/plugins/anchor'; //锚点
import 'tinymce/plugins/autolink'; //自动链接
import 'tinymce/plugins/autoresize'; //编辑器高度自适应,注:plugins里引入此插件时,Init里设置的height将失效
/**
 * 这个组件会在你刷新或路由跳转时出现一个弹窗提示。我不需要所以注释掉
 */
//import 'tinymce/plugins/autosave'; //自动存稿
import 'tinymce/plugins/charmap'; //特殊字符
import 'tinymce/plugins/code'; //编辑源码
import 'tinymce/plugins/codesample'; //代码示例
import 'tinymce/plugins/directionality'; //文字方向
import 'tinymce/plugins/emoticons'; //表情
import 'tinymce/plugins/fullscreen'; //全屏
import 'tinymce/plugins/help'; //帮助
import 'tinymce/plugins/image'; //插入编辑图片
import 'tinymce/plugins/importcss'; //引入css
import 'tinymce/plugins/insertdatetime'; //插入日期时间
import 'tinymce/plugins/link'; //超链接
import 'tinymce/plugins/lists'; //列表插件
import 'tinymce/plugins/media'; //插入编辑媒体
import 'tinymce/plugins/nonbreaking'; //插入不间断空格
import 'tinymce/plugins/pagebreak'; //插入分页符
import 'tinymce/plugins/preview'; //预览
import 'tinymce/plugins/quickbars'; //快速工具栏
import 'tinymce/plugins/save'; //保存
import 'tinymce/plugins/searchreplace'; //查找替换
import 'tinymce/plugins/table'; //表格
import 'tinymce/plugins/template'; //内容模板
import 'tinymce/plugins/visualblocks'; //显示元素范围
import 'tinymce/plugins/visualchars'; //显示不可见字符
/**
 * 字数统计有bug,所以先注释掉
 */
//import 'tinymce/plugins/wordcount'; //字数统计
import {onMounted, onUnmounted} from "vue";

/**
 * 每次加载组件时,都会生成一个唯一id
 */
const id = 'vue-tinymce-' + +new Date() + ((Math.random() * 1000).toFixed(0) + '')

const tinyInit = () => {
  console.log(`#${id}`)
  tinymce.init({
    selector: `#${id}`,
    language: 'zh-Hans',
    promotion: false, //Upgrade是否开启
    branding: false, //tiny技术支持信息是否显示
    skin_url: '../tinymce/skins/ui/oxide',
    plugins: 'codesample preview searchreplace autolink directionality visualblocks visualchars image link media template table charmap pagebreak nonbreaking anchor insertdatetime advlist lists wordcount autosave', //使用image插件
    menu: {
      file: {title: '文件', items: 'newdocument'},
      edit: {title: '编辑', items: 'undo redo | cut copy paste pastetext | selectall'},
      insert: {title: '插入', items: 'image link media | template hr'},
      view: {title: '查看', items: 'visualaid'},
      format: {
        title: '格式',
        items: 'bold italic underline strikethrough superscript subscript | formats | removeformat'
      },
      table: {title: '表格', items: 'inserttable tableprops deletetable | cell row column'},
      tools: {title: '工具', items: 'spellchecker code'},
    },
    toolbar: 'preview codesample code forecolor backcolor styles directionality fontfamily fontsize searchreplace image  media link alignleft aligncenter alignright template table charmap pagebreak nonbreaking anchor insertdatetime advlist lists wordcount autosave ', //工具栏显示
    line_height_formats: '1 1.2 1.4 1.6 2', //行高
    font_size_formats: '12px 14px 16px 18px 20px 22px 24px 28px 32px 36px 48px 56px 72px', //字体大小
    font_family_formats: '微软雅黑=Microsoft YaHei,Helvetica Neue,PingFang SC,sans-serif;苹果苹方=PingFang SC,Microsoft YaHei,sans-serif;宋体=simsun,serif;仿宋体=FangSong,serif;黑体=SimHei,sans-serif;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;',

    file_browser_callback_types: 'file image media',//这个根据个人需要配置
    file_picker_callback: function (callback, value, meta) {
      console.log(meta.filetype) //打印上传的类型
      // // 要先模拟出一个input用于上传本地文件
      var input = document.createElement('input')
      input.setAttribute('type', 'file')
      // 你可以给input加accept属性来限制上传的文件类型
      // 例如:input.setAttribute('accept', '.jpg,.png')
      input.setAttribute('accept', '.ppt,.pptx,.jpg, .jpeg, .png, .gif,.pdf, .txt, .zip, .rar, .7z, .doc, .docx, .xls, .xlsx,.mp3, .mp4')
      input.click()
      input.onchange = function () {
        var file = this.files[0]
        // 下方被注释掉的是官方的一个例子
        // 放到下面给大家参考
        var reader = new FileReader()
        reader.onload = function () {
          console.log(window.tinymce) //打印tinymce编辑器里面的参数
          // Note: Now we need to register the blob in TinyMCEs image blob
          // registry. In the next release this part hopefully won't be
          // necessary, as we are looking to handle it internally.
          var id = 'blobid' + (new Date()).getTime()
          var blobCache = window.tinymce.activeEditor.editorUpload.blobCache
          var base64 = reader.result.split(',')[1]
          var blobInfo = blobCache.create(id, file, base64)
          blobCache.add(blobInfo) //
          // call the callback and populate the Title field with the file name
          callback(blobInfo.blobUri(), {text: file.name, title: file.name})
        }
        reader.readAsDataURL(file)
      }
    },
    init_instance_callback: function (editor) {
      console.log('Editor initialized', editor);
      console.log("初始化完成");
    },
  })
}
/**
 * 将数据放入
 */
const setContents = (newContent) => {
const editor = tinymce.get(id);
  if (editor) {
    editor.setContent(newContent);
  }
};

/**
 * 获得数据
 */
const getContents = () => {
const editor = tinymce.get(id);
  if (editor) {
    return editor.getContent()
  }
};
/**
 * 组件销毁
 */
const removeTiny = () => {
const editor = tinymce.get(id);
  if (editor) {
    editor.destroy()
  }
}

onMounted(() => {
  tinyInit()
});

/**
 * 当加载组件的页面退出、关闭或跳转到其他页面时,自动销毁组件
 */
onUnmounted(() => {
  console.log("组件销毁=》removeTiny")
  removeTiny()
})

// eslint-disable-next-line no-undef
defineExpose({
  setContents,
  getContents,
  removeTiny,
  tinyInit
})
</script>

<style scoped>

</style>

然后是组件的调用:test.vue

<template>
  <div>
    <TinyMce ref="tinyMce" />
    <el-button @click="testT" >功能测试</el-button>
    <el-button @click="testS">输入测试</el-button>
    <el-button @click="testC">输出测试</el-button>
  </div>
</template>

<script setup>
import TinyMce from '@/components/TinyMce.vue'
import {ref} from "vue";
const tinyMce = ref('')

const testT = () => {
  tinyMce.value.testFunction()
}
const testS = () => {
  tinyMce.value.setContents('<h1>测试功能</h1>')
}
const testC = () => {
  console.log(tinyMce.value.getContents())
}
</script>

<style scoped>

</style>

运行:

 输入功能:

输出数据:

有问题的话,可以直接评论区留言。

2024-01-25:在实际使用中发现了一些问题,现在做出修改->const editor = tinymce.get(id);定义为全局

撤回01-25的修改,会导致组件方法无法使用

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值