vue3的富文本编辑器-Tinymce

记录tinymce的使用方法,本地代理模式的。图片上传到自己的服务器。中文版的。可以看到源码的,并且可以编辑的

1.下载https://github.com/tinymce/tinymce
2.将下载tinymce-main.zip放到自己的vue的public目录下
3.安装依赖包 npm install @tinymce/tinymce-vue 
本页面可以直接拿去用,修改下上传地址为自己的就可以。我是将这个页面做成了组件tinyEditor/index.vue

<template>
  <div class="tiny-editor-container">
    <Editor
      tinymce-script-src="/tinymce/tinymce.min.js"
      license-key="gpl"
      v-model="content"
      :init="initOptions"
    />
  </div>
</template>

<script setup lang="ts">
import { ref, watch, computed } from 'vue';
import Editor from '@tinymce/tinymce-vue';
import axios from 'axios';
import { uploadUrl } from "@/config/base"; //上传地址
import { SPContants } from '@/config/sp_contants'; //我记录token的常量
import { getImgUrl } from '@/utils/tool_utils';//显示图片地址的(我的展示和上传不是第一个地址。你们是同一个的忽略)

const props = defineProps({
  modelValue: {
    type: String,
    default: '',
  },
  height: {
    type: [Number, String],
    default: 500,
  },
  plugins: {
    type: [String, Array],
    default: () => [
      'advlist', 'autolink', 'lists', 'link', 'image', 'charmap', 'preview', 'anchor', 'searchreplace', 'visualblocks', 'code', 'fullscreen', 'insertdatetime', 'media', 'table', 'help', 'wordcount', 'emoticons'
    ],
  },
  toolbar: {
    type: String,
    default: 'undo redo | blocks fontfamily fontsize | bold italic underline strikethrough | align left center right justify | bullist numlist outdent indent | link image media table | emoticons charmap | removeformat preview code fullscreen',
  }
});

const emit = defineEmits(['update:modelValue']);

const content = ref(props.modelValue);

watch(() => props.modelValue, (newValue) => {
  if (newValue !== content.value) {
    content.value = newValue;
  }
});

watch(content, (newValue) => {
  emit('update:modelValue', newValue);
});

//图片上传
const handleImageUpload = (blobInfo: any, progress: any) => new Promise((resolve, reject) => {
  const formData = new FormData();
  formData.append('file', blobInfo.blob(), blobInfo.filename());

  const tokenName = localStorage.getItem(SPContants.TokenName);
  const token = localStorage.getItem(SPContants.Token);
  const headers: any = {};
  if (tokenName && token) {
    headers[tokenName] = token;
  }

  axios.post(uploadUrl, formData, {
    headers: {
      ...headers,
      'Content-Type': 'multipart/form-data'
    },
    onUploadProgress: (e) => {
      if (e.total) {
        progress(Math.round((e.loaded / e.total) * 100));
      }
    }
  }).then(res => {
    if (res.data && res.data.data) {
      resolve(getImgUrl(res.data.data));
    } else {
      reject('上传失败');
    }
  }).catch(err => {
    reject('上传出错:' + err.message);
  });
});

const initOptions = computed(() => ({
  height: props.height,
  language: 'zh_CN',
  language_url: '/tinymce/langs/zh_CN.js',
  menubar: false,
  plugins: props.plugins,
  toolbar: props.toolbar,
  toolbar_mode: 'sliding',
  branding: false,
  promotion: false,
  elementpath: false,
  statusbar: true,
  // 使用本地资源时,可以添加额外的配置
  base_url: '/tinymce', // 确保 TinyMCE 知道去哪里找主题和皮肤
  suffix: '.min',
  images_upload_handler: handleImageUpload,
}));
</script>

<style scoped>
</style>
4.使用方式
//导入
import Editor from "@/components/tinyEditor/index.vue";
//使用
 <Editor v-model="content" :min-height="192"/>
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容