index.vue 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. <template>
  2. <Editor v-model="contentValue" :init="init" :disabled="disabled" :placeholder="placeholder" @onClick="onClick" />
  3. </template>
  4. <script setup name="Editor">
  5. import Editor from '@tinymce/tinymce-vue'
  6. import tinymce from 'tinymce/tinymce'
  7. import 'tinymce/themes/silver'
  8. import 'tinymce/icons/default'
  9. import 'tinymce/models/dom'
  10. // 引入编辑器插件
  11. import 'tinymce/plugins/code' // 编辑源码
  12. import 'tinymce/plugins/image' // 插入编辑图片
  13. import 'tinymce/plugins/link' // 超链接
  14. import 'tinymce/plugins/preview' // 预览
  15. import 'tinymce/plugins/table' // 表格
  16. import 'tinymce/plugins/lists' // 列表编号
  17. import 'tinymce/plugins/advlist' //高级列表编号
  18. const emit = defineEmits(['update:modelValue', 'onClick'])
  19. const props = defineProps({
  20. modelValue: {
  21. type: String,
  22. default: ''
  23. },
  24. placeholder: {
  25. type: String,
  26. default: ''
  27. },
  28. height: {
  29. type: Number,
  30. default: 300
  31. },
  32. disabled: {
  33. type: Boolean,
  34. default: false
  35. },
  36. plugins: {
  37. type: [String, Array],
  38. default: 'code image link preview table lists advlist kityformula-editor'
  39. },
  40. toolbar: {
  41. type: [String, Array],
  42. default:
  43. 'undo redo | forecolor backcolor bold italic underline strikethrough link | blocks fontfamily fontsize | \
  44. alignleft aligncenter alignright alignjustify outdent indent lineheight | bullist numlist | \
  45. image table preview | code selectall'
  46. },
  47. fileUploadFunction: {
  48. type: Function,
  49. default: undefined
  50. }
  51. })
  52. const init = ref({
  53. language_url: '/tinymce/langs/zh_CN.js',
  54. language: 'zh_CN',
  55. skin_url: '/tinymce/skins/ui/oxide',
  56. content_css: '/tinymce/skins/content/default/content.css',
  57. menubar: false,
  58. statusbar: true,
  59. plugins: props.plugins,
  60. toolbar: props.toolbar,
  61. fontsize_formats: '12px 14px 16px 18px 20px 22px 24px 28px 32px 36px 48px 56px 72px',
  62. height: props.height,
  63. placeholder: props.placeholder,
  64. branding: false,
  65. resize: true,
  66. elementpath: true,
  67. content_style: '',
  68. toolbar_mode: 'wrap',
  69. external_plugins: {
  70. 'kityformula-editor': '/tinymce/plugins/kityformula-editor/plugin.min.js'
  71. },
  72. automatic_uploads: false,
  73. images_upload_handler(blobInfo, progress) {
  74. return new Promise((resolve, reject) => {
  75. const param = new FormData()
  76. param.append('file', blobInfo.blob(), blobInfo.filename())
  77. props
  78. .fileUploadFunction(param)
  79. .then((data) => {
  80. return resolve(data)
  81. })
  82. .catch((err) => {
  83. return reject('err:' + err)
  84. })
  85. })
  86. },
  87. setup: (editor) => {
  88. editor.on('init', () => {
  89. // getBody().style.fontSize = '14px'
  90. })
  91. editor.ui.registry.addButton('numberedline', {
  92. text: '填空',
  93. onAction: function () {
  94. const count = editor.getBody().querySelectorAll('.gapfilling-span').length
  95. const lineNumber = count + 1
  96. const uuid = 'gapfilling-' + Date.now() + '-' + Math.floor(Math.random() * 10000)
  97. editor.insertContent(
  98. `<span class="gapfilling-span ${uuid}" style="color:red;padding:0 30px;margin:0 5px;border-bottom:3px double red;">${lineNumber}</span>&ZeroWidthSpace;`
  99. )
  100. }
  101. })
  102. }
  103. })
  104. const contentValue = ref(props.modelValue)
  105. watch(props, (newValue) => {
  106. contentValue.value = newValue.modelValue
  107. emit('update:modelValue', newValue.modelValue)
  108. })
  109. watch(contentValue, (newValue) => {
  110. emit('update:modelValue', newValue)
  111. })
  112. const onClick = (e) => {
  113. emit('onClick', e, tinymce)
  114. }
  115. onMounted(() => {
  116. tinymce.init({})
  117. })
  118. </script>