index.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. import WangEditor from 'wangeditor'
  2. import { onMounted, onBeforeUnmount, ref, computed, watchEffect, watch } from 'vue'
  3. import { formInputProps } from '../../form-input-props'
  4. import { defaultMenus } from './config'
  5. import { debounce, isEmpty, isArray } from '@cip/utils/util'
  6. export default {
  7. name: 'basicEditor',
  8. props: formInputProps,
  9. emits: ['update:modelValue'],
  10. setup (props, { emit }) {
  11. const editor = ref()
  12. const height = computed(() => {
  13. // 编辑器高度配置
  14. return props.config?.height ?? null
  15. })
  16. const menus = computed(() => {
  17. // 编辑器菜单配置
  18. const menu = props.config.menus
  19. if (isEmpty(menu) || menu === '') return defaultMenus
  20. if (!isArray(menu)) return menu.split(',')
  21. return menu
  22. })
  23. const colors = computed(() => {
  24. // 编辑器字体及背景色配置
  25. return props.config?.colors ?? null
  26. })
  27. const fontNames = computed(() => {
  28. // 编辑器字体配置
  29. return props.config?.fontNames ?? null
  30. })
  31. const fontSizes = computed(() => {
  32. // 编辑器字号配置
  33. return props.config?.fontSizes ?? null
  34. })
  35. const emotions = computed(() => {
  36. // 编辑器表情图标配置
  37. return props.config?.emotions ?? null
  38. })
  39. const showFullScreen = computed(() => {
  40. // 配置全屏功能按钮是否展示
  41. return props.config?.showFullScreen ?? true
  42. })
  43. const showMenuTooltips = computed(() => {
  44. // 是否显示菜单栏提示
  45. return props.config?.showMenuTooltips ?? true
  46. })
  47. const menuTooltipPosition = computed(() => {
  48. // 菜单栏提示上标(up)还是下标(down)
  49. return props.config?.menuTooltipPosition ?? 'up'
  50. })
  51. const pasteFilterStyle = computed(() => {
  52. // 是否开启粘贴样式过滤
  53. return props.config?.pasteFilterStyle ?? true
  54. })
  55. const pasteIgnoreImg = computed(() => {
  56. // 是否忽略粘贴内容的图片
  57. return props.config?.pasteIgnoreImg ?? null
  58. })
  59. const customUploadImg = computed(() => {
  60. // 自定义上传图片
  61. return props.config?.customUploadImg ?? null
  62. })
  63. const placeholder = computed(() => {
  64. // 默认占位符
  65. return props.config?.placeholder ?? null
  66. })
  67. const emitInput = debounce((value) => {
  68. emit('update:modelValue', value)
  69. }, 200)
  70. const clearEmptyKey = (obj) => {
  71. // 清空value为空的key
  72. // eslint-disable-next-line
  73. for (const i in obj) {
  74. if (isEmpty(obj[i]) || obj[i] === '') delete obj[i]
  75. }
  76. return obj
  77. }
  78. // 清空编辑器
  79. // const clear = (instance) => {
  80. // instance.text.clear()
  81. // }
  82. let instance
  83. onMounted(() => {
  84. createEditor()
  85. watchEffect(() => {
  86. // 初始载入内容
  87. if (instance.txt.html() === '') instance.txt.html(props.modelValue)
  88. })
  89. // 得到config配置初始化及表单设计渲染
  90. watch(() => props.config, () => {
  91. // 重新渲染修改过config配置的editor,待优化
  92. createEditor()
  93. // 初始载入内容
  94. if (instance.txt.html() === '') instance.txt.html(props.modelValue)
  95. }, { deep: true })
  96. })
  97. const createEditor = () => {
  98. if (instance) instance.destroy()
  99. instance = new WangEditor(editor.value)
  100. Object.assign(instance.config, clearEmptyKey({
  101. height: height.value,
  102. menus: menus.value,
  103. colors: colors.value,
  104. fontNames: fontNames.value,
  105. fontSizes: fontSizes.value,
  106. emotions: emotions.value,
  107. showFullScreen: showFullScreen.value,
  108. showMenuTooltips: showMenuTooltips.value,
  109. menuTooltipPosition: menuTooltipPosition.value,
  110. pasteFilterStyle: pasteFilterStyle.value,
  111. pasteIgnoreImg: pasteIgnoreImg.value,
  112. customUploadImg: customUploadImg.value,
  113. placeholder: placeholder.value,
  114. focus: false,
  115. zIndex: 0
  116. }), {
  117. onchange (val) {
  118. emitInput(val)
  119. }
  120. })
  121. instance.create()
  122. }
  123. onBeforeUnmount(() => {
  124. destroyInstance()
  125. })
  126. const destroyInstance = () => {
  127. instance.destroy()
  128. instance = null
  129. }
  130. return () => (
  131. <div ref={editor} style="width:100%" />
  132. )
  133. }
  134. }