index.vue 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. <template>
  2. <div>
  3. <textarea ref="codeMirrorRef"></textarea>
  4. </div>
  5. </template>
  6. <script>
  7. import { ref, onMounted, watch, markRaw, nextTick, computed } from 'vue'
  8. import { getUsingConfig, isJson } from '@cip/utils/util'
  9. import { generateProps, generateEmits } from '../helper/component-util'
  10. import { componentScheme } from './component.scheme'
  11. import CodeMirror from 'codemirror'
  12. import 'codemirror/lib/codemirror.css'
  13. import 'codemirror/mode/javascript/javascript'
  14. import 'codemirror/mode/xml/xml'
  15. import 'codemirror/mode/sql/sql'
  16. import 'codemirror/addon/hint/show-hint'
  17. import 'codemirror/addon/hint/sql-hint'
  18. import 'codemirror/addon/hint/javascript-hint'
  19. import 'codemirror/addon/hint/show-hint.css'
  20. import 'codemirror/addon/edit/closebrackets'
  21. import 'codemirror/theme/dracula.css'
  22. import 'codemirror/theme/3024-day.css'
  23. export default {
  24. name: 'CipCodeMirror',
  25. props: generateProps(componentScheme),
  26. emits: generateEmits(componentScheme),
  27. setup (props, { emit }) {
  28. const codeMirrorRef = ref()
  29. const codeMirror = ref()
  30. const _mode = computed(() => getUsingConfig(
  31. props.mode,
  32. props.type === 'json' ? 'application/json' : `text/${props.type}`))
  33. const getCodeMirrorInstance = () => {
  34. const instance = CodeMirror.fromTextArea(codeMirrorRef.value, {
  35. value: formatterValue(props.modelValue),
  36. mode: _mode.value,
  37. theme: props.theme,
  38. indentUnit: props.indentUnit,
  39. lineNumbers: props.lineNumbers,
  40. lineWrapping: false,
  41. readOnly: props.readonly,
  42. singleCursorHeightPerLine: false,
  43. extraKeys: {}
  44. })
  45. instance.setSize(props.width ?? '100%', props.height ?? 'auto')
  46. instance.on('change', (instance, obj) => {
  47. const { origin } = obj
  48. const value = instance.getValue()
  49. codeMirror.value.save()
  50. if (origin !== 'setValue') { // 非setValue导致的更新才emit
  51. emit('update:modelValue', value)
  52. }
  53. })
  54. instance.on('inputRead', function () {
  55. instance.showHint({
  56. completeSingle: false
  57. })
  58. })
  59. return instance
  60. }
  61. const formatterValue = (val) => {
  62. if (props.type === 'json' && val) {
  63. let data = val
  64. if (typeof val === 'string' && isJson(data)) {
  65. data = JSON.parse(data)
  66. }
  67. return JSON.stringify(data, null, 2) ?? ''
  68. } else {
  69. return val
  70. }
  71. }
  72. onMounted(() => {
  73. codeMirror.value = markRaw(getCodeMirrorInstance())
  74. watch(() => props.modelValue, (val, oldVal) => {
  75. const codeMirrorValue = codeMirror.value?.getValue?.()
  76. if (codeMirrorValue === val) return
  77. codeMirror.value.setValue(formatterValue(val) ?? '')
  78. nextTick(() => {
  79. codeMirror.value.refresh()
  80. })
  81. }, {
  82. immediate: true
  83. })
  84. })
  85. return {
  86. codeMirrorRef
  87. }
  88. }
  89. }
  90. </script>