TinymceEditor.vue 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. <template>
  2. <div class="content_1111">
  3. <Editor api-key="nfaxt3iz0ciqr1yg7zxzifvksvval28yl46wr1n0847mt0d3" :init="init" v-model="content" :disabled="disabled" ref="tinymce" />
  4. </div>
  5. </template>
  6. <script setup>
  7. import Editor from "@tinymce/tinymce-vue";
  8. import { getToken } from "/src/utils/auth";
  9. import { watch } from "vue";
  10. const { proxy } = getCurrentInstance();
  11. const props = defineProps({
  12. value: {
  13. type: String,
  14. default: "",
  15. },
  16. disabled: {
  17. type: Boolean,
  18. default: false,
  19. },
  20. plugins: {
  21. type: [String, Array],
  22. default: "lists link image table code help wordcount",
  23. }, //必填
  24. toolbar: {
  25. type: [String, Array],
  26. default:
  27. "font | fontsize | format | bold italic underline forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | table | image | removeformat",
  28. }, //必填
  29. });
  30. const emit = defineEmits(["updateValue"]);
  31. const content = ref(props.value);
  32. const toolbar = ref(props.toolbar);
  33. const plugins = ref(props.plugins);
  34. const disabled = ref(props.disabled);
  35. const tinymce = ref(null);
  36. const init = reactive({
  37. plugins: plugins,
  38. toolbar: toolbar,
  39. content_css: "tinymce-5", //主题tinymce-5-dark || tinymce-5 || default || writer || document || dark
  40. custom_undo_redo_levels: 50, //回退数量
  41. end_container_on_empty_block: true, //块级文本是否换行
  42. keep_styles: true, //回车是否保存原有样式,例如code块回车是否截断
  43. menubar: false, //是否开启顶部菜单 > false 关闭菜单 | 'edit insert view format table tools help' 菜单按照这里排序 | 参考:https://www.tiny.cloud/docs/tinymce/6/menus-configuration-options/
  44. toolbar_mode: "wrap", //功能栏是否换行 > | wrap 换行 | scrolling 滚动 | sliding 省略
  45. toolbar_location: "top", //菜单栏位置 > bottom 底部 | top 顶部
  46. style_formats_merge: true, //是否开启默认功能
  47. elementpath: false, //是否展示编辑层级 > p span
  48. resize: true, //调整宽高 > true 调整高 | false 不可调整宽高 | both 宽高可调
  49. language: "zh_CN", //中文
  50. paste_data_images: true, //是否打开黏贴图片功能
  51. font_formats:
  52. "微软雅黑='微软雅黑';宋体='宋体';黑体='黑体';仿宋='仿宋';楷体='楷体';隶书='隶书';幼圆='幼圆';Andale Mono=andale mono,times;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Trebuchet MS=trebuchet ms,geneva;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings", //字体
  53. fontsize_formats: "8pt 10pt 12pt 14pt 18pt 24pt 36pt", // 第二步
  54. convert_fonts_to_spans: true,
  55. font_size_style_values: "8pt,10pt,12pt,14pt,18pt,24pt,36pt",
  56. images_upload_url: import.meta.env.VITE_APP_BASE_API,
  57. images_upload_handler: (blobInfo, progress) =>
  58. new Promise((resolve, reject) => {
  59. if (blobInfo.blob().size / 1024 / 1024 > 5) {
  60. reject({ message: "上传失败,图片大小请控制在 5M 以内", remove: true });
  61. return;
  62. } else {
  63. const file = blobInfo.blob();
  64. proxy.post("/fileInfo/getSing", { fileName: blobInfo.filename() }).then((res) => {
  65. const otherData = res.uploadBody;
  66. const formData = new FormData();
  67. for (const key in otherData) {
  68. formData.append(key, otherData[key]);
  69. }
  70. formData.append("file", file);
  71. proxy.post("https://winfaster.obs.cn-south-1.myhuaweicloud.com", formData).then((data) => {
  72. if (res && typeof res.fileUrl == "string" && res.fileUrl) {
  73. resolve(res.fileUrl);
  74. }
  75. });
  76. });
  77. }
  78. }),
  79. images_upload_base_path: "/demo",
  80. });
  81. const changeHtml = (val) => {
  82. content.value = val;
  83. };
  84. onMounted(() => {});
  85. defineExpose({
  86. changeHtml,
  87. });
  88. watch(
  89. () => content.value,
  90. (val) => {
  91. emit("updateValue", val);
  92. }
  93. );
  94. </script>
  95. <style lang="scss" scope>
  96. // .mce-content-body {
  97. // .mce-item-table:not([border]),
  98. // .mce-item-table:not([border]) caption,
  99. // .mce-item-table:not([border]) td,
  100. // .mce-item-table:not([border]) th,
  101. // .mce-item-table[border="0"],
  102. // .mce-item-table[border="0"] caption,
  103. // .mce-item-table[border="0"] td,
  104. // .mce-item-table[border="0"] th,
  105. // table[style*="border-width: 0px"],
  106. // table[style*="border-width: 0px"] caption,
  107. // table[style*="border-width: 0px"] td,
  108. // table[style*="border-width: 0px"] th {
  109. // border: none !important;
  110. // }
  111. // }
  112. </style>