CoolFace
Apppublic

zhemima/msmail

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes
MonacoEditor.vue135 linesDownload Raw Back to components
1<template>2  <div ref="editorContainer" class="h-full"></div>3</template>4 5<script setup lang="ts">6import { ref, onMounted, watch, onBeforeUnmount } from 'vue';7import monaco from '@monaco-editor/loader';8 9const props = defineProps<{10  value: string,11  originalValue?: string,12  language?: string,13  options?: Record<string, any>,14}>();15const emit = defineEmits(['update:value']);16 17const editorContainer = ref<HTMLElement>();18let editorInstance: any = null;19let monacoInstance: any = null;20let editorModel: any = null;21 22// 创建编辑器的函数23const createEditor = () => {24  if (!editorContainer.value || !monacoInstance) return;25  26  // 如果已存在编辑器实例,先销毁27  if (editorInstance) {28    editorInstance.dispose();29    editorInstance = null;30  }31 32  const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);33  const commonOptions = {34    language: props.language || 'json',35    minimap: { enabled: !isMobile },36    fontSize: isMobile ? 16 : 14,37    lineNumbers: isMobile ? 'off' as const : 'on' as const,38    scrollBeyondLastLine: false,39    automaticLayout: true,40    ...props.options41  };42 43  // 每次都创建新模型,确保内容刷新44  if (editorModel) {45    editorModel.dispose();46  }47  editorModel = monacoInstance.editor.createModel(props.value, props.language);48 49  if (props.originalValue !== undefined) {50    // 创建差异编辑器51    const originalModel = monacoInstance.editor.createModel(props.originalValue, props.language);52    editorInstance = monacoInstance.editor.createDiffEditor(editorContainer.value, {53      ...commonOptions,54      readOnly: false,55      renderSideBySide: true,56      ignoreTrimWhitespace: false,57      renderOverviewRuler: true,58      diffWordWrap: 'on',59    });60 61    editorInstance.setModel({62      original: originalModel,63      modified: editorModel64    });65    const modifiedEditor = editorInstance.getModifiedEditor();66    modifiedEditor.onDidChangeModelContent(() => {67      emit('update:value', modifiedEditor.getValue());68    });69  } else {70    // 创建普通编辑器71    editorInstance = monacoInstance.editor.create(editorContainer.value, {72      ...commonOptions,73      model: editorModel74    });75    editorInstance.onDidChangeModelContent(() => {76      emit('update:value', editorInstance.getValue());77    });78  }79};80 81onMounted(() => {82  monaco.init().then(instance => {83    monacoInstance = instance;84    createEditor();85  });86});87 88// 监听 value 和 originalValue 的变化89watch([() => props.value, () => props.originalValue], ([newVal, newOriginalVal], [oldVal, oldOriginalVal]) => {90  // 判断是否需要重建编辑器91  const modeChanged =92    (oldOriginalVal === undefined && newOriginalVal !== undefined) ||93    (oldOriginalVal !== undefined && newOriginalVal === undefined);94    95  if (modeChanged) {96    // 编辑器模式变化,重新创建97    createEditor();98  } else if (editorInstance) {99    if (props.originalValue !== undefined) {100      // 差异模式下更新内容101      const model = editorInstance.getModel();102      if (model && model.original && model.original.getValue() !== newOriginalVal) {103        model.original.setValue(newOriginalVal || '');104      }105      if (model && model.modified && model.modified.getValue() !== newVal) {106        model.modified.setValue(newVal || '');107      }108    } else {109      // 普通模式下更新内容110      if (editorInstance.getValue() !== newVal) {111        editorInstance.setValue(newVal || '');112      }113    }114  }115}, { deep: true });116 117onBeforeUnmount(() => {118  if (editorInstance) {119    editorInstance.dispose();120  }121  if (editorModel) {122    editorModel.dispose();123  }124  editorInstance = null;125  editorModel = null;126});127</script>128 129<style scoped>130:deep(.monaco-diff-editor),131:deep(.monaco-editor) {132  height: 100%;133}134</style>135