index.vue 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. <template>
  2. <div>
  3. <Editor :api-key="aipKey" :init="config" v-model="content" v-bind="$attrs" />
  4. </div>
  5. </template>
  6. <script setup lang="ts">
  7. import '/admin/public/tinymce/tinymce.min'
  8. import '/admin/public/tinymce/themes/silver/theme.min'
  9. import '/admin/public/tinymce/icons/default/icons.min'
  10. import '/admin/public/tinymce/models/dom/model.min'
  11. // css
  12. import '/admin/public/tinymce/skins/ui/oxide/skin.min.css'
  13. // plugins
  14. import '/admin/public/tinymce/plugins/preview/plugin.min'
  15. import '/admin/public/tinymce/plugins/searchreplace/plugin.min'
  16. import '/admin/public/tinymce/plugins/autolink/plugin.min'
  17. import '/admin/public/tinymce/plugins/directionality/plugin.min'
  18. import '/admin/public/tinymce/plugins/visualblocks/plugin.min'
  19. import '/admin/public/tinymce/plugins/visualchars/plugin.min'
  20. import '/admin/public/tinymce/plugins/fullscreen/plugin.min'
  21. import '/admin/public/tinymce/plugins/image/plugin.min'
  22. import '/admin/public/tinymce/plugins/link/plugin.min'
  23. import '/admin/public/tinymce/plugins/media/plugin.min'
  24. import '/admin/public/tinymce/plugins/template/plugin.min'
  25. import '/admin/public/tinymce/plugins/code/plugin.min'
  26. import '/admin/public/tinymce/plugins/codesample/plugin.min'
  27. import '/admin/public/tinymce/plugins/table/plugin.min'
  28. import '/admin/public/tinymce/plugins/charmap/plugin.min'
  29. import '/admin/public/tinymce/plugins/pagebreak/plugin.min'
  30. import '/admin/public/tinymce/plugins/nonbreaking/plugin.min'
  31. import '/admin/public/tinymce/plugins/anchor/plugin.min'
  32. import '/admin/public/tinymce/plugins/insertdatetime/plugin.min'
  33. import '/admin/public/tinymce/plugins/advlist/plugin.min'
  34. import '/admin/public/tinymce/plugins/lists/plugin.min'
  35. import '/admin/public/tinymce/plugins/wordcount/plugin.min'
  36. import '/admin/public/tinymce/plugins/autosave/plugin.min'
  37. import '/admin/public/tinymce/plugins/emoticons/plugin.min'
  38. // lang
  39. import '/admin/public/tinymce/langs/zh-CN'
  40. import Editor from '@tinymce/tinymce-vue'
  41. import { env } from '/admin/support/helper'
  42. import Http from '/admin/support/http'
  43. import Message from '/admin/support/message'
  44. import { ref, watch } from 'vue'
  45. const props = defineProps({
  46. modelValue: {
  47. type: String,
  48. default: '',
  49. require: true,
  50. },
  51. width: {
  52. type: [Number, String],
  53. required: false,
  54. default: 'auto',
  55. },
  56. height: {
  57. type: [Number, String],
  58. required: false,
  59. default: 'auto',
  60. },
  61. language: {
  62. type: String,
  63. default: 'zh-CN',
  64. },
  65. placeholder: {
  66. type: String,
  67. default: '在这里输入内容',
  68. },
  69. plugins: {
  70. type: String,
  71. default:
  72. 'preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template code ' +
  73. 'codesample table charmap pagebreak nonbreaking anchor insertdatetime advlist lists wordcount autosave emoticons',
  74. },
  75. toolbar: {
  76. type: Array,
  77. default: [
  78. 'undo redo restoredraft cut copy paste pastetext forecolor backcolor bold italic underline strikethrough link anchor alignleft aligncenter alignright alignjustify outdent indent bullist numlist blockquote subscript superscript removeformat styleselect formatselect fontselect fontsizeselect ' +
  79. 'table upload image axupimgs media emoticons charmap hr pagebreak insertdatetime ' +
  80. 'selectall visualblocks searchreplace code print preview indent2em fullscreen',
  81. ],
  82. },
  83. })
  84. const aipKey: string = 's1ntkmnev0ggx0hhaqnubrdxhv0ly99uyrdbckeaycx7iz6v'
  85. const uploaded = (blobInfo, progress) =>
  86. new Promise((resolve, reject) => {
  87. if (blobInfo.blob().size / 1024 / 1024 > 10) {
  88. Message.error('上传失败,图片大小请控制在 10M 以内')
  89. } else {
  90. let params = new FormData()
  91. params.append('image', blobInfo.blob())
  92. Http.post(env('VITE_BASE_URL') + 'upload/image', params)
  93. .then(res => {
  94. if (res.data.code === 10000) {
  95. resolve(res.data.data.path)
  96. } else {
  97. Message.error(res.message)
  98. }
  99. })
  100. .catch(() => {
  101. Message.error('Server Error!')
  102. })
  103. }
  104. })
  105. const config = {
  106. base_url: '/admin/public/tinymce',
  107. language: props.language,
  108. placeholder: props.placeholder,
  109. width: props.width,
  110. height: props.height,
  111. plugins: props.plugins,
  112. toolbar: props.toolbar,
  113. branding: false,
  114. // menubar: false,
  115. images_upload_handler: uploaded,
  116. }
  117. const emits = defineEmits(['update:modelValue'])
  118. const content = ref(props.modelValue)
  119. // 创建的时候
  120. watch(content, value => {
  121. emits('update:modelValue', value)
  122. })
  123. // 回显监听
  124. watch(
  125. () => props.modelValue,
  126. value => {
  127. content.value = value
  128. },
  129. )
  130. </script>
  131. <style scoped>
  132. .tinymce-boxz > textarea {
  133. display: none;
  134. }
  135. </style>
  136. <style>
  137. /* 隐藏apikey没有绑定这个域名的提示 */
  138. .tox-notifications-container .tox-notification--warning {
  139. display: none !important;
  140. }
  141. .tox {
  142. z-index: 9999 !important;
  143. }
  144. .tox-promotion {
  145. display: none !important;
  146. }
  147. </style>