94 lines
1.9 KiB
Vue
94 lines
1.9 KiB
Vue
<template>
|
|
<div class="ui-editor-container">
|
|
<div ref="editorContainer" class="editor-surface"></div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, onMounted, onUnmounted, watch } from 'vue'
|
|
import loader from '@monaco-editor/loader'
|
|
|
|
const props = defineProps({
|
|
modelValue: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
language: {
|
|
type: String,
|
|
default: 'javascript'
|
|
},
|
|
theme: {
|
|
type: String,
|
|
default: 'vs-dark'
|
|
},
|
|
options: {
|
|
type: Object,
|
|
default: () => ({})
|
|
}
|
|
})
|
|
|
|
const emit = defineEmits(['update:modelValue', 'change'])
|
|
|
|
const editorContainer = ref(null)
|
|
let editorInstance = null
|
|
|
|
onMounted(async () => {
|
|
try {
|
|
const monaco = await loader.init()
|
|
|
|
editorInstance = monaco.editor.create(editorContainer.value, {
|
|
value: props.modelValue,
|
|
language: props.language,
|
|
theme: props.theme,
|
|
automaticLayout: true,
|
|
minimap: { enabled: false },
|
|
scrollBeyondLastLine: false,
|
|
fontSize: 14,
|
|
lineNumbers: 'on',
|
|
roundedSelection: false,
|
|
scrollbar: {
|
|
vertical: 'auto',
|
|
horizontal: 'auto'
|
|
},
|
|
...props.options
|
|
})
|
|
|
|
// 监听内容变化
|
|
editorInstance.onDidChangeModelContent(() => {
|
|
const value = editorInstance.getValue()
|
|
emit('update:modelValue', value)
|
|
emit('change', value)
|
|
})
|
|
} catch (error) {
|
|
console.error('Failed to load Monaco Editor:', error)
|
|
}
|
|
})
|
|
|
|
// 监听外部值变化
|
|
watch(() => props.modelValue, (newValue) => {
|
|
if (editorInstance && editorInstance.getValue() !== newValue) {
|
|
editorInstance.setValue(newValue)
|
|
}
|
|
})
|
|
|
|
onUnmounted(() => {
|
|
if (editorInstance) {
|
|
editorInstance.dispose()
|
|
}
|
|
})
|
|
</script>
|
|
|
|
<style scoped>
|
|
.ui-editor-container {
|
|
width: 100%;
|
|
height: 400px;
|
|
border: 1px solid #d1d5db;
|
|
border-radius: 6px;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.editor-surface {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
</style> |