123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- <script setup>
- import { ref, onMounted, onBeforeUnmount, watch, nextTick } from "vue";
- import loader from "@monaco-editor/loader";
- const props = defineProps({
- value: String,
- language: {
- type: String,
- default: "python",
- },
- theme: {
- type: String,
- default: "vs-light",
- },
- });
- const emit = defineEmits(["update:value"]);
- const editorContainer = ref(null);
- let editorInstance = null;
- // 调试:打印容器尺寸
- const logContainerSize = () => {
- if (!editorContainer.value) {
- // console.log('Editor container not yet mounted');
- return;
- }
- const rect = editorContainer.value.getBoundingClientRect();
- // console.log('Container size:', rect.width, 'x', rect.height);
- };
- // 初始化 Monaco 编辑器
- const initEditor = async () => {
- const monaco = await loader.init();
-
- // 等待容器渲染完成
- await nextTick();
-
- // 添加额外延迟确保布局完成(仅开发时需要)
- if (process.env.NODE_ENV === 'development') {
- await new Promise(resolve => setTimeout(resolve, 50));
- }
- // 再次检查尺寸
- const rect = editorContainer.value.getBoundingClientRect();
- // console.log('Final container size:', rect.width, 'x', rect.height);
- editorInstance = monaco.editor.create(editorContainer.value, {
- value: props.value || "",
- language: props.language,
- theme: props.theme,
- });
- editorInstance.onDidChangeModelContent(() => {
- const value = editorInstance.getValue();
- emit("update:value", value); // 触发v-model更新
- });
- // 强制立即布局
- editorInstance.layout();
- };
- // 处理窗口大小变化
- const handleResize = () => {
- if (editorInstance) {
- // console.log('Window resized, updating editor layout');
- editorInstance.layout();
- }
- };
- onMounted(() => {
- // console.log('Component mounted, initializing editor...');
- initEditor();
- });
- onBeforeUnmount(() => {
- // console.log('Component unmounting, disposing editor...');
- window.removeEventListener('resize', handleResize);
- editorInstance?.dispose();
- });
- // 监听语言变化
- watch(
- () => props.language,
- (newLanguage) => {
- if (editorInstance) {
- console.log('Language changed to:', newLanguage);
- loader.init().then((monaco) => {
- monaco.editor.setModelLanguage(editorInstance.getModel(), newLanguage);
- });
- }
- }
- );
- // 监听值变化
- watch(
- () => props.value,
- (newValue) => {
- if (editorInstance && editorInstance.getValue() !== newValue) {
- console.log('Value updated programmatically');
- editorInstance.setValue(newValue);
- }
- }
- );
- </script>
- <template>
- <div ref="editorContainer" class="editorContainer"></div>
- </template>
- <style scoped>
- .editorContainer {
- height: 400px;
- width: 100%;
- border: 1px solid #ccc; /* 调试边框 */
- position: relative; /* 确保正确的定位上下文 */
- }
- /* 强制设置 Monaco 容器尺寸 */
- .editorContainer :deep(.monaco-editor) {
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- }
- </style>
|