Vue3 uses rich text tinymce-vue

1. Install
npm install @tinymce/tinymce-vue -S

2. Encapsulate and build a component

<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>

3. Page introduction and use

<editor :value="value"/>

Finish

Note : When using it, the following error will occasionally appear . The js of the rich text plug-in cannot be found on the server, resulting in the rich
text not being loaded. Put it inside (if Chinese is required)
insert image description here


insert image description here

insert image description here

insert image description here

insert image description here

Then the page imports

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

![Insert picture description here](https://img-blog.csdnimg.cn/fed81ac4872345168c1cb86fe0b3b453.png

In this way, the loading of rich text will be faster, and the js file will not be found.

Guess you like

Origin blog.csdn.net/qq_41697998/article/details/127422056