Ueditor.vue 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. <template>
  2. <div>
  3. <!-- 富文本编辑器 -->
  4. <VueUeditorWrap
  5. ref="Ueditor"
  6. v-model="content"
  7. :config="myConfig"
  8. @before-init="addCustomButtom"
  9. />
  10. <!-- 文件选择器 -->
  11. <FilesModal
  12. ref="FilesModal"
  13. :fileType="filesModalType"
  14. :multiple="true"
  15. @handleSubmit="handleSelectSubmit"
  16. />
  17. </div>
  18. </template>
  19. <script>
  20. import _ from 'lodash'
  21. import PropTypes from 'ant-design-vue/es/_util/vue-types'
  22. import VueUeditorWrap from 'vue-ueditor-wrap'
  23. import { defaultConfig } from './config'
  24. import { FilesModal } from '@/components/Modal'
  25. import FileTypeEnum from '@/common/enum/file/FileType'
  26. export default {
  27. name: 'Ueditor',
  28. components: {
  29. FilesModal,
  30. VueUeditorWrap
  31. },
  32. model: {
  33. prop: 'value',
  34. event: 'change'
  35. },
  36. props: {
  37. // 内容
  38. // eslint-disable-next-line vue/require-default-prop
  39. value: PropTypes.string,
  40. // 编辑器配置
  41. config: PropTypes.object.def({})
  42. },
  43. data () {
  44. const myConfig = _.merge(defaultConfig, this.config)
  45. return {
  46. myConfig,
  47. content: '',
  48. filesModalType: FileTypeEnum.IMAGE.value
  49. }
  50. },
  51. watch: {
  52. value: {
  53. // 首次加载的时候执行函数
  54. immediate: true,
  55. handler (val) {
  56. this.content = val
  57. }
  58. },
  59. content (newVal) {
  60. // 使用setTimeout防止热更新时报错
  61. setTimeout(() => {
  62. this.$emit('change', newVal)
  63. }, 10)
  64. }
  65. },
  66. methods: {
  67. // 注册自定义组件
  68. addCustomButtom (editorId) {
  69. this.registerSimpleupload(editorId)
  70. this.registerInsertvideo(editorId)
  71. },
  72. // 注册图片选择按钮
  73. registerSimpleupload (editorId) {
  74. const app = this
  75. window.UE.registerUI('simpleupload', function (editor, uiName) {
  76. // 创建一个 button
  77. var btn = new window.UE.ui.Button({
  78. // 按钮的名字
  79. name: uiName,
  80. // 提示
  81. title: '插入图片',
  82. // 需要添加的额外样式,可指定 icon 图标,图标路径参考常见问题 2
  83. cssRules: '',
  84. // 点击时执行的命令
  85. onclick: () => {
  86. // 打开文件选择器
  87. app.handleSelectImage()
  88. }
  89. })
  90. // 因为你是添加 button,所以需要返回这个 button
  91. return btn
  92. }, undefined /* 指定添加到工具栏上的哪个位置,默认时追加到最后 */, editorId /* 指定这个 UI 是哪个编辑器实例上的,默认是页面上所有的编辑器都会添加这个按钮 */)
  93. },
  94. // 注册视频选择按钮
  95. registerInsertvideo (editorId) {
  96. const app = this
  97. window.UE.registerUI('insertvideo', function (editor, uiName) {
  98. // 创建一个 button
  99. var btn = new window.UE.ui.Button({
  100. // 按钮的名字
  101. name: uiName,
  102. // 提示
  103. title: '插入视频',
  104. // 需要添加的额外样式,可指定 icon 图标,图标路径参考常见问题 2
  105. cssRules: '',
  106. // 点击时执行的命令
  107. onclick: () => {
  108. // 打开文件选择器
  109. app.handleSelectVideo()
  110. }
  111. })
  112. // 因为你是添加 button,所以需要返回这个 button
  113. return btn
  114. }, undefined /* 指定添加到工具栏上的哪个位置,默认时追加到最后 */, editorId /* 指定这个 UI 是哪个编辑器实例上的,默认是页面上所有的编辑器都会添加这个按钮 */)
  115. },
  116. // 打开图片选择器
  117. handleSelectImage () {
  118. this.filesModalType = FileTypeEnum.IMAGE.value
  119. this.$nextTick(() => {
  120. this.$refs.FilesModal.show()
  121. })
  122. },
  123. // 打开视频选择器
  124. handleSelectVideo () {
  125. this.filesModalType = FileTypeEnum.VIDEO.value
  126. this.$nextTick(() => {
  127. this.$refs.FilesModal.show()
  128. })
  129. },
  130. // 文件库modal确认回调
  131. handleSelectSubmit (selectedItems) {
  132. const app = this
  133. if (selectedItems.length > 0) {
  134. let content = ''
  135. if (app.filesModalType === FileTypeEnum.IMAGE.value) {
  136. content = selectedItems.map(item => `<p><img src="${item.preview_url}" /></p>`)
  137. }
  138. if (app.filesModalType === FileTypeEnum.VIDEO.value) {
  139. content = selectedItems.map(item => `<p><video style="width: 100%; height: 240px;" src="${item.external_url}" controls>${item.file_id}</video></p>`)
  140. }
  141. this.inserthtml(content.join(''))
  142. }
  143. },
  144. inserthtml (content) {
  145. const editor = this.$refs.Ueditor.editor
  146. editor.execCommand('inserthtml', content)
  147. }
  148. }
  149. }
  150. </script>