vue3 使用富文本tinymce-vue

一、安装
npm install @tinymce/tinymce-vue -S

二、封装建一个组件

<template>
  <div>
    <Editor
      api-key="xxxxx"
      tinymceScriptSrc="/tinymce/tinymce.min.js"
      :init="{
        language: 'zh_CN',
        height: 500,
        paste_data_images: true, // 允许粘贴图像
        paste_webkit_styles: 'all',
        automatic_uploads: true,
        convert_urls: false,
        image_caption: true,
        content_style: `
        *{
            margin:0;
            padding:0;
          }
          body{
            font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, Helvetica,
              Segoe UI, Arial, Roboto, PingFang SC, miui, Hiragino Sans GB,
              Microsoft Yahei, sans-serif !important;
          }
          h1,h2,h3,h4,h5,h6,h7{
            font-size: 18px;
          }
          p,font{
            font-size: 16px;
            font-weight: 400;
            color: #262626;
            line-height: 24px;
            text-align: justify;
            word-break: break-all;
            letter-spacing: 1.5px;
          }
          p{
            text-indent:0;
            margin:0;
          }
          strong span{
            display: block;
          }
          div img,p img,img,span img{
            width:50% !important;
            height:auto;
            text-align:center;
            border-radius: 4px;
            display: block;
            margin: 15px auto 0 auto;
          }
          figcaption{
            text-align:center !important;
            margin: 20px 0 !important;
          }
          figure{
            margin: 0 auto !important;
          }
          `,
        toolbar: [
          'image media video bold fontsize forecolor backcolor italic underline strikethrough styleselect fontsizeselect alignleft aligncenter alignright alignjustify outdent indent lineheight cut copy outdent indent undo redo  blockquote table preview fullscreen',
        ],
        menubar: false,
        branding: false,
        fontsize_formats: '11px 12px 14px 16px 17px 18px 24px 36px 48px',
        lineheight_formats: '10px 20px 30px 40px 50px 60px',
        imagetools_toolbar: 'imageoptions',
        file_picker_callback: file_picker_callback,
        paste_preprocess: paste_preprocess,
        init_instance_callback: init_instance_callback,
        images_upload_handler: example_image_upload_handle,
        urlconverter_callback: urlconverter_callback,
      }"
      v-model="content"
      :plugins="['image', 'fullscreen', 'media', 'preview', 'paste']"
      @change="handleChange"
    ></Editor>
  </div>
</template>
<script lang="ts" setup>
import {
      
       ref, watch } from "vue";
import Editor from "@tinymce/tinymce-vue";
import {
      
       uploadFiles } from "@/utils/funtional";
import axios from "axios";
import {
      
       message } from "ant-design-vue";

let props = defineProps<{
      
      
  readOnly?: boolean;
  value: string;
}>();

let emits = defineEmits(["handleChange"]);

let content = ref<string>();
let editorRef: any;

watch(
  () => props.value,
  (val) => {
      
      
    content.value = val;
  },
  {
      
      
    deep: true,
    immediate: true,
  }
);
// 图片直接粘贴
const paste_preprocess = (_: any, args: Record<string, any>) => {
      
      
  if (args.content.indexOf("xiumi") !== -1) {
      
      
    return args.content;
  }

  const styleTag = /\s+style="[^"]*"/gi;

  args.content = args.content
    .replace(styleTag, () => {
      
      
      return "";
    })
    .replace(/(&nbsp;)|(<br>)|(<br\/>)/gi, () => {
      
      
      return "";
    });
};

// 文件上传
const file_picker_callback = (
  callback: (key: string) => void,
  value: string,
  meta: Record<string, string>
) => {
      
      
  if (meta.filetype === "image") {
      
      
    if (!value) return;
    axios({
      
      
      url: value,
      method: "get",
      responseType: "arraybuffer",
    }).then((res) => {
      
      
      let code = btoa(
        new Uint8Array(res.data).reduce(
          (data, byte) => data + String.fromCharCode(byte),
          ""
        )
      );
      let a = document.createElement("a");
      a.setAttribute("href", "data:image/png;base64," + code);
      a.download = "image" + new Date().getTime();
      a.click();
      a.remove();
    });
  }
  if (meta.filetype === "media") {
      
      
    let fileInput = document.createElement("input");

    fileInput.setAttribute("type", "file");

    fileInput.setAttribute("accept", ".mp4");

    fileInput.click();

    fileInput.addEventListener("change", async (e: any) => {
      
      
      let url = await uploadFiles(e.target.files[0]);
      callback(url);
      fileInput.remove();
    });
  }
};
// 图片上传
const example_image_upload_handle = async (
  blobInfo: Record<string, any>,
  success: (url: string) => void,
  failFun: (mes: string) => void
) => {
      
      
  let maxSize = blobInfo.blob().size / 1024 / 1024;
  if (maxSize > 10) {
      
      
    return failFun("请上传10M以内的图片");
  }
  let url = await uploadFiles(blobInfo.blob());
  success(url);
};

const urlconverter_callback = (url: string) => {
      
      
  return url;
};

const init_instance_callback = (ref: any) => {
      
      
  editorRef = ref;
  if (props.readOnly) {
      
      
    editorRef.setMode("readonly");
  }
};

const handleChange = () => {
      
      
  emits("handleChange", content.value);
};
</script>

三、页面引入使用

<editor :value="value"/>

完成

注意:
用的时候偶尔会出现以下报错,服务器上找不到富文本插件的js,导致富文本加载不出来
在这里插入图片描述
解决办法:

在这里插入图片描述
里面找到
在这里插入图片描述
复制到
在这里插入图片描述
到官网去下来中文包,建一个langs的文件夹,放在里面(需要中文的情况)
在这里插入图片描述

然后页面引入

tinymceScriptSrc="/tinymce/tinymce.min.js"

![在这里插入图片描述](https://img-blog.csdnimg.cn/fed81ac4872345168c1cb86fe0b3b453.png

这样富文本加载会变快,也不会出现找不到js文件的情况了

猜你喜欢

转载自blog.csdn.net/qq_41697998/article/details/127422056