index.vue 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. <template>
  2. <div :id="editorId" class="editorContainer"></div>
  3. </template>
  4. <script setup>
  5. import { ref, onMounted, onUnmounted, watch, computed, toRaw } from 'vue'
  6. import * as monaco from 'monaco-editor'
  7. const props = defineProps({
  8. value: String,
  9. language: String,
  10. })
  11. const emit = defineEmits(['change'])
  12. const editor = ref(null)
  13. const editorId = computed(() => `editor_${Math.random().toString(36).slice(2, 11)}`)
  14. const getEditorValue = () => toRaw(editor.value)?.getValue() || ''
  15. let resizeObserver = null
  16. onMounted(() => {
  17. const el = document.getElementById(editorId.value)
  18. if (!el) {
  19. // console.warn('[MonacoEdit]找不到容器元素')
  20. return
  21. }
  22. const initEditor = () => {
  23. if (editor.value || el.clientWidth === 0 || el.clientHeight === 0) return
  24. // console.log('[MonacoEdit]尺寸可用,初始化编辑器')
  25. monaco.editor.defineTheme('custom-light', {
  26. base: 'vs',
  27. inherit: true,
  28. rules: [],
  29. colors: {
  30. 'editorGutter.background': '#EEEEEE',
  31. },
  32. })
  33. editor.value = monaco.editor.create(el, {
  34. value: props.value || '',
  35. language: props.language || 'python',
  36. minimap: { enabled: true },
  37. colorDecorators: true,
  38. readOnly: false,
  39. theme: 'custom-light',
  40. automaticLayout: true,
  41. })
  42. editor.value.onDidChangeModelContent(() => {
  43. emit('change', getEditorValue())
  44. })
  45. // console.log('[MonacoEdit]初始化完成')
  46. }
  47. // 使用 ResizeObserver 监听尺寸变化
  48. resizeObserver = new ResizeObserver(() => {
  49. if (el.clientWidth > 0 && el.clientHeight > 0 && !editor.value) {
  50. initEditor()
  51. }
  52. })
  53. resizeObserver.observe(el)
  54. })
  55. onUnmounted(() => {
  56. if (editor.value) {
  57. editor.value.dispose()
  58. editor.value = null
  59. }
  60. if (resizeObserver) {
  61. resizeObserver.disconnect()
  62. resizeObserver = null
  63. }
  64. })
  65. </script>
  66. <style>
  67. .editorContainer {
  68. height: 400px !important;
  69. }
  70. </style>