Editor.vue 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. <script setup lang="ts">
  2. import { onBeforeUnmount, computed, PropType, unref, nextTick, ref, watch, shallowRef } from 'vue'
  3. import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
  4. import { IDomEditor, IEditorConfig, i18nChangeLanguage } from '@wangeditor/editor'
  5. import { propTypes } from '@/utils/propTypes'
  6. import { isNumber } from '@/utils/is'
  7. import { ElMessage } from 'element-plus'
  8. import { useLocaleStore } from '@/store/modules/locale'
  9. const localeStore = useLocaleStore()
  10. const currentLocale = computed(() => localeStore.getCurrentLocale)
  11. i18nChangeLanguage(unref(currentLocale).lang)
  12. const props = defineProps({
  13. editorId: propTypes.string.def('wangeEditor-1'),
  14. height: propTypes.oneOfType([Number, String]).def('500px'),
  15. editorConfig: {
  16. type: Object as PropType<IEditorConfig>,
  17. default: () => undefined
  18. },
  19. defaultHtml: propTypes.string.def('')
  20. })
  21. // 编辑器实例,必须用 shallowRef
  22. const editorRef = shallowRef<IDomEditor>()
  23. const handleCreated = (editor: IDomEditor) => {
  24. editorRef.value = editor
  25. }
  26. const emit = defineEmits(['change'])
  27. // 编辑器配置
  28. const editorConfig = computed((): IEditorConfig => {
  29. return Object.assign(
  30. {
  31. readOnly: false,
  32. customAlert: (s: string, t: string) => {
  33. switch (t) {
  34. case 'success':
  35. ElMessage.success(s)
  36. break
  37. case 'info':
  38. ElMessage.info(s)
  39. break
  40. case 'warning':
  41. ElMessage.warning(s)
  42. break
  43. case 'error':
  44. ElMessage.error(s)
  45. break
  46. default:
  47. ElMessage.info(s)
  48. break
  49. }
  50. },
  51. autoFocus: false,
  52. scroll: true,
  53. uploadImgShowBase64: true
  54. },
  55. props.editorConfig || {}
  56. )
  57. })
  58. const editorStyle = computed(() => {
  59. return {
  60. height: isNumber(props.height) ? `${props.height}px` : props.height
  61. }
  62. })
  63. // 回调函数
  64. const handleChange = (editor: IDomEditor) => {
  65. emit('change', editor)
  66. }
  67. // 组件销毁时,及时销毁编辑器
  68. onBeforeUnmount(() => {
  69. const editor = unref(editorRef.value)
  70. if (editor === null) return
  71. // 销毁,并移除 editor
  72. editor?.destroy()
  73. })
  74. const getEditorRef = async (): Promise<IDomEditor> => {
  75. await nextTick()
  76. return unref(editorRef.value) as IDomEditor
  77. }
  78. defineExpose({
  79. getEditorRef
  80. })
  81. const show = ref(true)
  82. watch(
  83. () => props.defaultHtml,
  84. () => {
  85. show.value = false
  86. setTimeout(() => {
  87. show.value = true
  88. }, 0)
  89. }
  90. )
  91. </script>
  92. <template>
  93. <div v-if="show" class="border-1 border-solid border-[var(--tags-view-border-color)]">
  94. <!-- 工具栏 -->
  95. <Toolbar
  96. :editor="editorRef"
  97. :editorId="editorId"
  98. class="border-bottom-1 border-solid border-[var(--tags-view-border-color)]"
  99. />
  100. <!-- 编辑器 -->
  101. <Editor
  102. :editorId="editorId"
  103. :defaultConfig="editorConfig"
  104. :defaultHtml="defaultHtml"
  105. :style="editorStyle"
  106. @on-change="handleChange"
  107. @onCreated="handleCreated"
  108. />
  109. </div>
  110. </template>
  111. <style src="@wangeditor/editor/dist/css/style.css"></style>