index.vue 2.77 KB
<template>
  <div :style="cacheConfigStyle">
    <div ref="el" class="go-editor-area" :style="{ width, height }"></div>
    <EditorWorker></EditorWorker>
    <div style="margin-left:10px;">  
      <n-gradient-text type="danger">
       {{ errorText }}
      </n-gradient-text>
</div>
  </div>
</template>

<script lang="ts" setup>
import { onMounted, watch, PropType, ref, computed } from 'vue'
import { useMonacoEditor } from './index.hook'
import { EditorWorker } from './index'

const props = defineProps({
  width: {
    type: String as PropType<string>,
    default: '100%'
  },
  height: {
    type: String as PropType<string>,
    default: '90vh'
  },
  language: {
    type: String as PropType<string>,
    default: 'typescript'
  },
  preComment: {
    type: String as PropType<string>,
    default: ''
  },
  modelValue: {
    type: String as PropType<string>,
    default: ''
  },
  editorOptions: {
    type: Object as PropType<object>,
    default: () => ({})
  },
  config: {
    type: Boolean as PropType<boolean>,
    default: false
  },
})

const emits = defineEmits(['blur', 'update:modelValue'])

const { el, updateVal, getEditor, createEditor } = useMonacoEditor(props.language)

const updateMonacoVal = (_val?: string) => {
  const { modelValue, preComment } = props
  const val = preComment ? `${preComment}\n${_val || modelValue}` : _val || modelValue
  updateVal(val)
}

onMounted(() => {
  const monacoEditor = createEditor(props.editorOptions)
  monacoEditor!.onDidChangeModelContent(() => {
    emits('update:modelValue', monacoEditor!.getValue())
  })
  monacoEditor!.onDidBlurEditorText(() => {
    emits('blur')
  })
  updateMonacoVal()
})

const errorText = ref('')

const cacheConfigStyle = computed(() => {
  const configStyle = {
    display:'flex',
    justifyContent: 'space-between',
    alignItems: 'center'
  }
  return props.config ? configStyle : ''
})

watch(
  () => props.modelValue,
  (val: string) => {
    if(props.language === 'json') {
      try {
        const res = JSON.parse(val)
        if(res) {
          errorText.value = ''
        }
      } catch (_) {
        errorText.value = 'JSON格式有误,请仔细检查!'
      }
    }
    val !== getEditor()?.getValue() && updateMonacoVal(val)
  }
)
</script>

<style lang="scss" scoped>
.go-editor-area {
  position: relative;
  border-radius: 4px;
  overflow: hidden;
  padding: 5px;
  padding-left: 0;
  box-sizing: border-box;
  background-color: rgba(0, 0, 0, 0);
  @include deep() {
    .margin,
    .monaco-editor,
    .inputarea.ime-input {
      background-color: rgba(0, 0, 0, 0);
    }

    .monaco-editor-background {
      background-color: rgba(0, 0, 0, 0);
      @include fetch-bg-color('filter-color-shallow');
    }
    .margin {
      @include fetch-bg-color('filter-color-shallow');
    }
  }
}
</style>