tinymce使用

3,255 阅读2分钟

1# 1.中文文档

tinymce.ax-z.cn/

2.安装

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

3.tinymce 默认英文

www.tiny.cloud/get-tiny/la…

image.png

在 public 目录下新建 tinymce,将上面下载的语言包解压到该目录 在 node_modules 里面找到 tinymce, 将 skins 目录复制到 public/tinymce 里面 最终形成以下目录形式:

image.png

4.封装 tinymce

<template>
  <div class="tinymce-editor">
    <Editor
      v-model="content"
      :init="init"
      :disabled="disabled"
      @onClick="onClick"
    />
  </div>
</template>

<script setup lang="ts">
import { ref, watch, onMounted } from "vue";
import tinymce from "tinymce/tinymce";
import Editor from "@tinymce/tinymce-vue";
import { http } from "@/utils/http";

// 核心
import "tinymce/themes/silver/theme";
import "tinymce/models/dom/model";

// 插件
import "tinymce/icons/default";
import "tinymce/plugins/advlist";
import "tinymce/plugins/anchor";
import "tinymce/plugins/autolink";
import "tinymce/plugins/autoresize";
import "tinymce/plugins/image";
import "tinymce/plugins/link";
import "tinymce/plugins/lists";
import "tinymce/plugins/media";
import "tinymce/plugins/code";
import "tinymce/plugins/lists";
import "tinymce/plugins/table";
import "tinymce/plugins/wordcount";

// Props 定义
interface Props {
  modelValue?: string;
  disabled?: boolean;
  plugins?: string | string[];
  toolbar?: string | string[];
}

const props = withDefaults(defineProps<Props>(), {
  modelValue: "",
  disabled: false,
  plugins: "advlist autolink lists link image table wordcount",
  toolbar:
    "undo redo | formatselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image media table | removeformat"
});

// Emits 定义
const emit = defineEmits<{
  (e: "update:modelValue", value: string): void;
  (e: "onClick", event: any, editor: any): void;
}>();

// 编辑器内容
const content = ref(props.modelValue);

// 编辑器配置
const init = {
  language_url: "/tinymce/langs/zh_CN.js",
  language: "zh_CN",
  skin_url: "/tinymce/skins/ui/oxide",
  content_css: "/tinymce/skins/content/default/content.css",
  height: 300,
  plugins: props.plugins,
  toolbar: props.toolbar,
  branding: false,
  menubar: false,
  // 修改图片上传处理器
  images_upload_handler: async (blobInfo: any) => {
    try {
      const formData = new FormData(); // 修正变量名
      formData.append("image", blobInfo.blob());

      const response = await http.request(
        "post",
        "/api/cmsapi/post/image/upload",
        {
          data: formData,
          headers: {
            "Content-Type": "multipart/form-data"
          }
        }
      );

      if (response.code === 200) {
        return `${import.meta.env.VITE_API_URL}/${response.data.image_url}`;
      } else {
        throw new Error(response.message || "上传失败");
      }
    } catch (error) {
      console.error("上传错误:", error);
      throw new Error("图片上传失败,请重试");
    }
  },
  // 文件选择配置
  file_picker_types: "image",
  images_file_types: "jpg,jpeg,png,gif",
  image_advtab: true,
  // 允许拖拽上传
  draggable_modal: true,
  // 图片上传配置
  images_upload_base_path: import.meta.env.VITE_API_URL,
  // 图片上传URL验证
  images_upload_credentials: true,
  // 开启调试模式,方便排查问题
  debug: true
};

// 监听 props 变化
watch(
  () => props.modelValue,
  newValue => {
    if (content.value !== newValue) {
      content.value = newValue;
    }
  }
);

// 监听内容变化
watch(
  () => content.value,
  newValue => {
    emit("update:modelValue", newValue);
  }
);

// 点击事件处理
const onClick = (e: any) => {
  emit("onClick", e, tinymce);
};

// 清空内容方法
const clear = () => {
  content.value = "";
};

// 初始化编辑器
onMounted(() => {
  tinymce.init({});
});

// 暴露方法给父组件
defineExpose({
  clear
});
</script>

<style lang="scss" scoped>
.tinymce-editor {
  width: 100%;
}

:deep(.tox-tinymce) {
  border-radius: 4px;
}
</style>

<style lang="scss">
.tox-tinymce-aux {
  z-index: 99999 !important;
}
.tinymce.ui.FloatPanel {
  z-index: 99;
}
</style>

5.使用

import Tinymce from "@/components/Tinymce/index.vue";


  <Tinymce
    v-model="localFormData.content"
    :disabled="false"
    @onClick="handleClick"
  />

参考:learnku.com/articles/34… gitee.com/sweetwisdom…