【Vue3】tinymce富文本编辑器的使用

1.简介

TinyMCE是一款易用、且功能强大的所见即所得的富文本编辑器。同类程序有:UEditor、Kindeditor、Simditor、CKEditor、wangEditor、Suneditor、froala等等。

TinyMCE的优势:

  • 开源可商用,基于LGPL2.1
  • 插件丰富,自带插件基本涵盖日常所需功能
  • 接口丰富,可扩展性强,有能力可以无限拓展功能
  • 界面好看,符合现代审美
  • 提供经典、内联、沉浸无干扰三种模式(详见“介绍与入门”)
  • 对标准支持优秀(自v5开始)
  • 多语言支持,官网可下载几十种语言。

tinyMCE中文文档

2.使用

2.1 下载

npm install tinymce @tinymce/tinymce-vue -S

然后把node_modules/tinymec下的skins文件夹复制到public文件夹下
最后下载语言包,把里面的zh_CN.js也放进
中文包下载地址

在这里插入图片描述

2.2 封装组件

//TEditor.vue
<template>
  <editor v-model="content" tag-name="div" :init="init" />
</template>

<script lang="ts">
import {
    
     upload } from "../api/upload";
import tinymce from "tinymce/tinymce";
import Editor from "@tinymce/tinymce-vue";
//根据需要引入
import "tinymce/themes/silver/theme"; // 引用主题文件
import "tinymce/icons/default"; // 引用图标文件
import "tinymce/plugins/link";
import "tinymce/plugins/code";
import "tinymce/plugins/table";//插入表格
import "tinymce/plugins/autoresize";
import "tinymce/plugins/autosave";
import "tinymce/plugins/charmap"; //特殊字符
import "tinymce/plugins/code"; //查看源码
import "tinymce/plugins/codesample"; //插入代码1
import "tinymce/plugins/directionality"; //
import "tinymce/plugins/fullscreen"; //全屏
import "tinymce/plugins/image"; //图片
import "tinymce/plugins/imagetools"; //图片工具
import "tinymce/plugins/importcss"; //图片工具
import "tinymce/plugins/media"; //媒体插入
import "tinymce/plugins/preview"; //预览
import "tinymce/plugins/quickbars"; //快捷菜单
import "tinymce/plugins/searchreplace"; //查询替换
import "tinymce/plugins/tabfocus"; //
import "tinymce/plugins/textpattern"; //
import {
    
     onMounted, ref, watch } from "vue";

export default {
    
    
  props: ["modelValue"],
  components: {
    
    
    editor: Editor,
  },
  emits: {
    
     "update:modelValue": null },
  setup(props: any, context: any) {
    
    
    const init = {
    
    
      language_url: "/public/tinymce/langs/zh_CN.js", // 中文语言包路径
      language: "zh_CN",
      skin_url: "/public/tinymce/skins/ui/oxide", // skin路径
      content_css: "/public/tinymce/skins/content/default/content.css", //以css文件方式自定义可编辑区域的css样式,css文件需自己创建并引入
      menubar: false, // 隐藏菜单栏
      autoresize_bottom_margin: 50,
      max_height: 500,
      min_height: 350,
      //   height: 320,
      toolbar_mode: "none",
      plugins:
        "textpattern  tabfocus  searchreplace  quickbars preview  media  importcss imagetools image  fullscreen  directionality codesample code charmap link code table  autoresize autosave link", // 插件需要import进来
      toolbar:
        "formats undo redo  fontsizeselect fontselect   searchreplace preview pagebreak media image|outdent indent aligncenter alignleft alignright alignjustify lineheight  underline quicklink h2 h3 blockquote numlist bullist table removeformat forecolor backcolor bold italic  strikethrough  charmap link codesample code  preview fullscreen",//工具栏展示的
      content_style: "p {margin: 5px 0; font-size: 14px}",
      fontsize_formats: "12px 14px 16px 18px 24px 36px 48px 56px 72px",
      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;",
      branding: false,
      elementpath: false,
      resize: false, // 禁止改变大小
      statusbar: false, // 隐藏底部状态栏
      // paste_data_images: true, // 允许粘贴图像

      file_picker_types: "file image media",
      //文件上传
      file_picker_callback: function (callback: any, value: any, meta: any) {
    
    
        //文件分类
        var filetype =
          ".pdf, .txt, .zip, .rar, .7z, .doc, .docx, .xls, .xlsx, .ppt, .pptx, .mp3, .mp4";
        //为不同插件指定文件类型
        switch (meta.filetype) {
    
    
          case "image":
            filetype = ".jpg, .jpeg, .png, .gif";
            break;
          case "media":
            filetype = ".mp3, .mp4";
            break;
          case "file":
          default:
        }
        //模拟出一个input用于添加本地文件
        var input = document.createElement("input");
        input.setAttribute("type", "file");
        input.setAttribute("accept", filetype);
        input.click();
        input.onchange = function (v: any) {
    
    
          var file = v.target.files[0];
          var formData = new FormData();
          formData.append("file", file, file.name);
          upload(formData).then((res) => {
    
    
            callback(res.file.url, {
    
     title: file.name });
          });
        };
      },
      //   图片上传
      images_upload_handler: async (blobInfo: any, success: any) => {
    
    
      //官网写法,返回的图片路径为base64
       // var reader = new FileReader();
        // reader.readAsDataURL(blobInfo.blob());
        // reader.onload = function () {
    
    
        //   success(this.result);
        // };
        
        //改写,通过自己的upload接口,返回的图片时正常的url格式
        var form = new FormData();
        form.append("file", blobInfo.blob(), blobInfo.filename());
        upload(form).then((res) => {
    
    
          success(res.file.url);
        });
      },
    };
    const content = ref();
    onMounted(() => {
    
    
      content.value = props.modelValue;
    });
    watch(
      () => content.value,
      () => {
    
    
        revert_data(content.value);
      }
    );
    tinymce.init; // 初始化
    const revert_data = (content: any) => {
    
    
    //实现数据的双向绑定
      context.emit("update:modelValue", content);
    };
    return {
    
    
      init,
      revert_data,
      content,
    };
  },
};
</script>

使用组件

<template>
  <div>
 <TEditor ref="editor" v-model="state.content" />
  </div>
</template>

<script setup>
import {
    
     reactive,watch} from 'vue'
import TEditor from "@/components/TEditor.vue";
</script>
<style lang="scss" scoped>
state=reactive({
    
    
content:"",//获取TEditor的内容
})
watch(()=>state.content,()=>{
    
    
//监控TEditor内容的变化
console.log(state.content)
))

</style>

在这里插入图片描述
获取文章内容:
在这里插入图片描述
具体使用上传图片和上传文件
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/CYL_2021/article/details/129478590