vue3 中引入tinymce富文本

vue3 中引入tinymce富文本

我用的是若依的 Vue3 + Element Plus + Vite 框架,使用tinymce替换原富文本.

先说踩的坑和遇到的问题吧

  • 1.想看html源代码 需要引入code
javascript 复制代码
import "tinymce/plugins/code";
  • 2.字体库在vue3中的属性是'font_family_formats'
javascript 复制代码
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;',

tinymce版本

复制代码
"@tinymce/tinymce-vue": "^6.1.0",
"tinymce": "^7.4.1",

vue3下载安装可参考,以下为代码

参考:https://blog.csdn.net/m0_73358221/article/details/129358814

main.js引入

javascript 复制代码
// 富文本组件
import Editor from "@/components/TinymceEditor.vue"
app.component('Editor', Editor)

页面使用

html 复制代码
<editor
  v-model="formData.noticeContent"
  @input="
    (val) => {
      formData.noticeContent = val;
    }
  "
></editor>

editor组件代码

html 复制代码
<template>
  <div>
    <Editor v-model="content" :init="myTinyInit"></Editor>
  </div>
</template>

<script setup>
import {
  computed,
  onMounted,
  reactive,
  ref,
  watch,
} from "vue";
import tinymce from "tinymce/tinymce";
import Editor from "@tinymce/tinymce-vue";
import "tinymce/icons/default/icons";
import "tinymce/themes/silver";
import "tinymce/models/dom/model";

//按需引入插件
import "tinymce/plugins/image";
import "tinymce/plugins/table";
import "tinymce/plugins/lists";
import "tinymce/plugins/code";
import "tinymce/plugins/link";
import "tinymce/plugins/help";
import "tinymce/plugins/wordcount";

// import axios from "axios";
// import {useStore} from "vuex";
// import {ElNotification} from "element-plus";

const props = defineProps({
  modelValue: {
    type: String,
    default: "",
  }
});
const emit = defineEmits(["input"]);

// const store = useStore();
const myTinyInit = reactive({
  // width: '100%',
  height: 600,
  width: "750px",
  language_url: import.meta.env.VITE_TINYMCE_PATH + "/tinymce/langs/zh_CN.js", //如果语言包不存在,指定一个语言包路径
  language: "zh_CN", //语言
  branding: false,
  menubar: true,
  resize: false,
  skin_url: import.meta.env.VITE_TINYMCE_PATH + "/tinymce/skins/ui/oxide", //手动引入
  content_css: import.meta.env.VITE_TINYMCE_PATH + "/tinymce/skins/content/default/content.css", //手动引入
  toolbar_mode: "wrap",
  plugins: "code lists link image table help wordcount", // 插件
  statusbar: false,
  promotion: false,
  // toolbar: props.toolbar, // 工具栏
  toolbar: "accordion accordionremove | blocks fontselect fontfamily fontsize | bold italic underline | align numlist bullist | link | table media | lineheight outdent indent| forecolor backcolor removeformat | charmap emoticons | code fullscreen preview", // 工具栏
  theme: "silver", //主题
  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;',
  //图片上传方法(注意!!:要使用 promise 对象中的 resolve 返回图片路径,否则会报错)
  // images_upload_handler: (blobInfo) => new Promise((resolve, reject) => {
  //     let formData = new FormData();
  //     formData.append('file', blobInfo.blob(), blobInfo.filename());
  //     axios.post(`/api/backend/upload`, formData, {
  //         headers: ({
  //             'Content-Type': 'multipart/form-data',
  //             'Authorization': "Bearer " + store.state.user.accessToken
  //         })
  //     }).then(res => {
  //         if (res.data.code === 1) {
  //             resolve(`/image_manipulation${res.data.data.filePath}`)
  //         } else {
  //             // ElNotification.warning(res.data.msg)
  //         }
  //     }).catch(error => {
  //         reject(error);
  //     })
  // }),
});

const initContent = computed(() => {
  return props.modelValue;
});

onMounted(() => {
  tinymce.init({
    font_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;',
  });
});

const content = ref();
watch(
  initContent,
  (newVal) => {
    content.value = newVal;
  },
  { deep: true, immediate: true }
);

watch(
  content,
  (newVal) => {
    emit("input", newVal);
  },
  { deep: true }
);
</script>

<style scoped lang="scss"></style>
相关推荐
RuoyiOffice2 天前
SpringBoot3+Vue3 最推荐的开源 OA 系统 2026:流程驱动、资源闭环、多端互通
spring boot·vue3·flowable·oa·协同办公·spring boot 3·开源oa
鱼与宇3 天前
Element-plus离线访问(适用内网)
elementui·vue3
我就是DaLing呀!5 天前
vue3 + 独立的数据管理 Store实现视频剪辑功能
前端·typescript·vue3·canvas·store
我才是银古7 天前
当 360° 全景遇上真实地图:Vue 3 实现全景-地图双向联动的工程实践
3d·vue3·360影像
XLYcmy9 天前
HTML/CSS/JS 基础与 Vue 技术栈深度解析
java·前端·css·html·vue3·vue2·api
码视野11 天前
基于 Spring Boot + Vue3 的【大学英语四六级 (CET-4/6) 作文智能评分与句式润色系统】设计与实现(含PRD/三端高保真源码/大屏)
java·前端·人工智能·spring boot·后端·vue3
码视野12 天前
基于 Spring Boot + Vue3 的【高校化学实验室安全准入考试与危化品配伍排查系统】设计与实现(含PRD/三端高保真源码/大屏)
前端·人工智能·spring boot·后端·安全·vue3
fxshy12 天前
WebGIS 游戏化实践:基于 Cesium + Vue3 实现全球飞行模拟系统:从球体坐标、飞行动力学到地形碰撞实战
游戏·vue3·cesium·webgis·飞行模拟
jonyleek13 天前
技术实践:基于 Vue3 + Spring Cloud 微服务实现私有化文档系统的类 SaaS 协同体验
微服务·私有化部署·vue3·springcloud·协同编辑·jvs企业文档·无忧企业文档
码视野13 天前
基于 Vue3 + Element Plus 的【智慧社区洗车养车与上门流动洗车预约调度系统】设计与实现(含PRD/三端源码/大屏)
前端·javascript·vue.js·人工智能·vue3