BasicEditor.vue 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. <template>
  2. <div>
  3. <div style="border: 1px solid #ccc; margin-top: 10px;">
  4. <Toolbar
  5. :editor="editorRef"
  6. :defaultConfig="toolbarConfig"
  7. :mode="mode"
  8. style="border-bottom: 1px solid #ccc"
  9. />
  10. <Editor
  11. :defaultConfig="editorConfig"
  12. :mode="mode"
  13. v-model="valueHtml"
  14. style="height: 400px; overflow-y: hidden;"
  15. @onCreated="handleCreated"
  16. @onChange="handleChange"
  17. @onDestroyed="handleDestroyed"
  18. @onFocus="handleFocus"
  19. @onBlur="handleBlur"
  20. @customAlert="customAlert"
  21. />
  22. </div>
  23. <Button icon="md-add" size="small" @click="displayCodeState = !displayCodeState">显示代码视图</Button>
  24. <div style="margin-top: 10px;" v-if="displayCodeState">
  25. <textarea v-model="valueHtml" readonly style="width: 100%; height: 200px; outline: none;"></textarea>
  26. </div>
  27. </div>
  28. </template>
  29. <script>
  30. import '@wangeditor/editor/dist/css/style.css'
  31. import { onBeforeUnmount, ref, shallowRef, onMounted } from 'vue'
  32. import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
  33. import api from '@/request/apiConfig' //真实接口配置\
  34. import {compressFileM} from '@/utils/system/uploadCompress.js'
  35. export default {
  36. components: { Editor, Toolbar },
  37. setup() {
  38. // 编辑器实例,必须用 shallowRef,重要!
  39. const editorRef = shallowRef()
  40. // 内容 HTML
  41. const valueHtml = ref('')
  42. // 显示代码视图开关
  43. const displayCodeState = ref(false)
  44. const toolbarConfig = {}
  45. const editorConfig = {
  46. placeholder: '请输入内容...',
  47. MENU_CONF: {
  48. // 上传图片配置
  49. uploadImage: {
  50. server: api.apiManager + '/manager/images/upload', // 上传图片地址
  51. timeout: 60 * 1000, // 60s
  52. fieldName: 'file',
  53. headers: {'X-AIYANGNIU-SIGNATURE':localStorage.aynUserToken},
  54. maxFileSize: 10240 * 1024 * 1024, // 10G
  55. onBeforeUpload(file) {
  56. return file
  57. // return false 会阻止上传
  58. },
  59. onSuccess(file, res) {
  60. // console.log('onSuccess', file, res)
  61. },
  62. // 编辑器自身原因,无法识别上传成功,放在failed里执行
  63. onFailed(file, res) {
  64. },
  65. onError(file, err, res) {
  66. alert(err.message)
  67. },
  68. customInsert(res, insertFn) {
  69. insertFn(res.data, '图片', '')
  70. },
  71. },
  72. // 上传视频配置
  73. uploadVideo:{
  74. onInsertedVideo(videoNode) {
  75. console.log('inserted video', videoNode)
  76. },
  77. server: api.apiManager + '/manager/images/upload', // 上传图片地址
  78. timeout: 6000 * 1000, // 6000s
  79. fieldName: 'file',
  80. headers: {'X-AIYANGNIU-SIGNATURE':localStorage.aynUserToken},
  81. maxFileSize: 5120 * 1024 * 1024, // 5G
  82. onBeforeUpload(file) {
  83. console.log('onBeforeUpload', file)
  84. return file // will upload this file
  85. },
  86. onSuccess(file, res) {
  87. console.log('onSuccess', file, res)
  88. },
  89. onFailed(file, res) {
  90. console.log('onFailed', file, res)
  91. },
  92. onError(file, err, res) {
  93. alert(err.message)
  94. console.error('onError', file, err, res)
  95. },
  96. customInsert(res, insertFn) {
  97. insertFn(res.data, '')
  98. },
  99. }
  100. }
  101. }
  102. // 组件销毁时,也及时销毁编辑器,重要!
  103. onBeforeUnmount(() => {
  104. const editor = editorRef.value
  105. if (editor == null) return
  106. editor.destroy()
  107. })
  108. // 编辑器回调函数
  109. const handleCreated = (editor) => {
  110. console.log('created', editor);
  111. editorRef.value = editor // 记录 editor 实例,重要!
  112. }
  113. const handleChange = (editor) => {
  114. // console.log('change:', editor.getHtml());
  115. }
  116. const handleDestroyed = (editor) => {
  117. // console.log('destroyed', editor)
  118. }
  119. const handleFocus = (editor) => {
  120. // console.log('focus', editor)
  121. }
  122. const handleBlur = (editor) => {
  123. // console.log('blur', editor)
  124. }
  125. const customAlert = (info, type) => {
  126. alert(`【自定义提示】${type} - ${info}`)
  127. }
  128. // 自动贴入内容
  129. const customPaste = (editor, event, callback) => {
  130. console.log('ClipboardEvent 粘贴事件对象',editor, event)
  131. // 自定义插入内容
  132. editor.insertText('xxx')
  133. // 返回值(注意,vue 事件的返回值,不能用 return)
  134. callback(false) // 返回 false ,阻止默认粘贴行为
  135. // callback(true) // 返回 true ,继续默认的粘贴行为
  136. }
  137. const insertText = () => {
  138. const editor = editorRef.value
  139. if (editor == null) return
  140. editor.insertText('hello world')
  141. }
  142. const printHtml = () => {
  143. const editor = editorRef.value
  144. if (editor == null) return
  145. console.log(editor.getHtml())
  146. }
  147. // 禁用富文本
  148. const disable = () => {
  149. const editor = editorRef.value
  150. if (editor == null) return
  151. editor.disable()
  152. }
  153. return {
  154. editorRef,
  155. mode: 'default',
  156. valueHtml,
  157. toolbarConfig,
  158. editorConfig,
  159. handleCreated,
  160. handleChange,
  161. handleDestroyed,
  162. handleFocus,
  163. handleBlur,
  164. customAlert,
  165. customPaste,
  166. insertText,
  167. printHtml,
  168. disable,
  169. displayCodeState,
  170. };
  171. }
  172. }
  173. </script>