RichTextEditor.vue 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. <template>
  2. <div class="rich-text-editor">
  3. <Toolbar
  4. style="border-bottom: 1px solid #ccc"
  5. :editor="editor"
  6. :defaultConfig="toolbarConfig"
  7. :mode="mode"
  8. />
  9. <Editor
  10. style="height: 500px; overflow-y: hidden;"
  11. v-model="html"
  12. :defaultConfig="editorConfig"
  13. :mode="mode"
  14. @onCreated="onEditorCreated"
  15. />
  16. <div class="bottom-bar">
  17. <button
  18. class="ui-button"
  19. @click="onClickCancel"
  20. >
  21. {{$i18n.t('common.cancel')}}
  22. </button>
  23. <button
  24. class="ui-button submit"
  25. @click="onClickOk"
  26. >
  27. {{$i18n.t('common.ok')}}
  28. </button>
  29. </div>
  30. <div class="dialog" style="z-index: 2000" v-if="isShowImageSelectionWindow">
  31. <MaterialSelector
  32. :title="$i18n.t('gather.select_material')"
  33. @cancle="isShowImageSelectionWindow = false"
  34. @submit="onSubmitFromImageMaterialSelector"
  35. :selectableType="['image']"
  36. :initialMaterialType="'image'"
  37. :isMultiSelection="true"
  38. />
  39. </div>
  40. <div class="dialog" style="z-index: 2000" v-if="isShowVideoSelectionWindow">
  41. <MaterialSelector
  42. :title="$i18n.t('gather.select_material')"
  43. @cancle="isShowVideoSelectionWindow = false"
  44. @submit="onSubmitFromVideoMaterialSelector"
  45. :selectableType="['video']"
  46. :initialMaterialType="'video'"
  47. :isMultiSelection="true"
  48. />
  49. </div>
  50. </div>
  51. </template>
  52. <script>
  53. import Vue from 'vue'
  54. import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
  55. import MaterialSelector from "@/components/materialSelector.vue";
  56. export default Vue.extend({
  57. components: {
  58. Editor,
  59. Toolbar,
  60. MaterialSelector,
  61. },
  62. props: {
  63. initialHtml: {
  64. type: String,
  65. defaut: '',
  66. }
  67. },
  68. data() {
  69. return {
  70. editor: null,
  71. html: this.initialHtml,
  72. toolbarConfig: {
  73. },
  74. editorConfig: {
  75. placeholder: 'fdf',
  76. MENU_CONF: {
  77. uploadImage: {
  78. customBrowseAndUpload: (insertFn) => {
  79. this.isShowImageSelectionWindow = true
  80. this.insertFn = insertFn
  81. }
  82. },
  83. uploadVideo: {
  84. customBrowseAndUpload: (insertFn) => {
  85. this.isShowVideoSelectionWindow = true
  86. this.insertFn = insertFn
  87. }
  88. },
  89. },
  90. },
  91. mode: 'default', // or 'simple',
  92. isShowImageSelectionWindow: false,
  93. isShowVideoSelectionWindow: false,
  94. insertFn: null,
  95. }
  96. },
  97. methods: {
  98. onEditorCreated(editor) {
  99. this.editor = Object.seal(editor) // 一定要用 Object.seal() ,否则会报错
  100. },
  101. onClickOk() {
  102. this.$emit('ok', this.html)
  103. },
  104. onClickCancel() {
  105. this.$emit('cancel')
  106. },
  107. onSubmitFromImageMaterialSelector(selected) {
  108. this.isShowImageSelectionWindow = false
  109. for (const selectedItem of selected) {
  110. this.insertFn(selectedItem.icon, `[${this.$i18n.t('gather.image')}: ${selectedItem.name}]`)
  111. }
  112. },
  113. onSubmitFromVideoMaterialSelector(selected) {
  114. this.isShowVideoSelectionWindow = false
  115. for (const selectedItem of selected) {
  116. console.log(selectedItem);
  117. this.insertFn(selectedItem.ossPath, selectedItem.ossPath + this.$videoImgOriginalSize)
  118. }
  119. },
  120. },
  121. mounted() {
  122. },
  123. beforeDestroy() {
  124. const editor = this.editor
  125. if (editor == null) return
  126. editor.destroy() // 组件销毁时,及时销毁编辑器
  127. }
  128. })
  129. </script>
  130. <style src="@wangeditor/editor/dist/css/style.css"></style>
  131. <style lang="less" scoped>
  132. .rich-text-editor {
  133. // border: 1px solid #ccc;
  134. border-radius: 4px;
  135. overflow: hidden;
  136. > .bottom-bar {
  137. padding: 10px;
  138. background-color: #fff;
  139. border-top: 1px solid #ccc;
  140. display: flex;
  141. justify-content: flex-end;
  142. align-items: center;
  143. > button {
  144. margin-left: 10px;
  145. }
  146. }
  147. }
  148. </style>