deotalandAi/packages/ui/plugins/editor/EditorPlugin.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>