Skip to content

Commit f538199

Browse files
committed
fix: make monaco editor works normally
1 parent 0aac8d1 commit f538199

File tree

3 files changed

+56
-43
lines changed

3 files changed

+56
-43
lines changed

src/editor/MonacoEditor.vue

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
<script setup lang="ts">
22
import Monaco from '../monaco/Monaco.vue'
3-
import { computed } from 'vue'
43
5-
const props = defineProps<{
4+
defineProps<{
65
value: string;
76
filename: string;
87
readonly?: boolean
@@ -15,29 +14,11 @@ const emits = defineEmits<{
1514
const onChange = (code: string) => {
1615
emits('change', code)
1716
}
18-
19-
const language = computed(() => {
20-
const filename = props.filename;
21-
if (filename.endsWith('.vue')) {
22-
return 'vue'
23-
}
24-
if (filename.endsWith('.html')) {
25-
return 'html'
26-
}
27-
if (filename.endsWith('.css')) {
28-
return 'css'
29-
}
30-
if (filename.endsWith('.ts')) {
31-
return 'typescript'
32-
}
33-
return 'javascript'
34-
})
3517
</script>
3618

3719
<template>
3820
<Monaco
39-
:value="value"
40-
:language="language"
41-
@save="onChange"
21+
@change="onChange"
22+
:filename="filename"
4223
/>
4324
</template>

src/monaco/Monaco.vue

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,18 @@ import { loadMonacoEnv, loadWasm } from './env';
33
loadMonacoEnv();
44
loadWasm();
55
</script>
6+
67
<script lang="ts" setup>
7-
import { onMounted, onBeforeUnmount, ref, shallowRef, nextTick, watchEffect } from 'vue';
8+
import { onMounted, onBeforeUnmount, ref, shallowRef, nextTick, watchEffect, inject, watch } from 'vue';
89
import * as monaco from 'monaco-editor-core';
910
import { getOrCreateModel } from './utils';
1011
import { loadGrammars, loadTheme } from 'monaco-volar'
12+
import { Store } from '../store';
1113
1214
const props = withDefaults(defineProps<{
13-
value?: string
14-
language?: string;
15-
readonly?: boolean
15+
filename: string;
16+
readonly?: boolean;
1617
}>(), {
17-
value: '',
1818
readonly: false
1919
})
2020
@@ -26,20 +26,28 @@ const emits = defineEmits<{
2626
const containerRef = ref<HTMLDivElement | null>();
2727
const ready = ref(false);
2828
const editor = shallowRef<monaco.editor.IStandaloneCodeEditor | undefined>(undefined);
29-
30-
const currentModel = shallowRef<monaco.editor.ITextModel>(
31-
getOrCreateModel(
32-
monaco.Uri.parse('file:///demo.vue'),
33-
'vue',
34-
props.value ?? ''
35-
)
36-
)
29+
const store = inject('store') as Store;
3730
3831
watchEffect(() => {
39-
if (currentModel.value.getValue() !== props.value) {
40-
currentModel.value.setValue(props.value)
32+
// create a model for each file in the store
33+
for (const filename in store.state.files) {
34+
const file = store.state.files[filename];
35+
if (monaco.editor.getModel(monaco.Uri.parse(`file:///${filename}`)))
36+
continue;
37+
getOrCreateModel(
38+
monaco.Uri.parse(`file:///${filename}`),
39+
file.language,
40+
file.code
41+
);
4142
}
42-
})
43+
44+
// dispose of any models that are not in the store
45+
for (const model of monaco.editor.getModels()) {
46+
if (store.state.files[model.uri.toString().substring('file:///'.length)])
47+
continue;
48+
model.dispose();
49+
}
50+
});
4351
4452
onMounted(async () => {
4553
const theme = await loadTheme();
@@ -52,7 +60,7 @@ onMounted(async () => {
5260
5361
const editorInstance = monaco.editor.create(containerRef.value, {
5462
theme,
55-
model: currentModel.value,
63+
model: null,
5664
readOnly: props.readonly,
5765
automaticLayout: true,
5866
scrollBeyondLastLine: false,
@@ -65,11 +73,19 @@ onMounted(async () => {
6573
});
6674
editor.value = editorInstance
6775
68-
await loadGrammars(editorInstance);
76+
watch(() => props.filename, () => {
77+
if (!editorInstance) return;
78+
const file = store.state.files[props.filename];
79+
if (!file) return null;
80+
const model = getOrCreateModel(
81+
monaco.Uri.parse(`file:///${props.filename}`),
82+
file.language,
83+
file.code
84+
);
85+
editorInstance.setModel(model);
86+
}, { immediate: true });
6987
70-
editorInstance.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, () => {
71-
emits('save', editorInstance.getValue());
72-
});
88+
await loadGrammars(editorInstance);
7389
7490
editorInstance.onDidChangeModelContent(() => {
7591
emits('change', editorInstance.getValue());

src/store.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,22 @@ export class File {
3939
this.code = code
4040
this.hidden = hidden
4141
}
42+
43+
get language() {
44+
if (this.filename.endsWith('.vue')) {
45+
return 'vue'
46+
}
47+
if (this.filename.endsWith('.html')) {
48+
return 'html'
49+
}
50+
if (this.filename.endsWith('.css')) {
51+
return 'css'
52+
}
53+
if (this.filename.endsWith('.ts')) {
54+
return 'typescript'
55+
}
56+
return 'javascript'
57+
}
4258
}
4359

4460
export interface StoreState {

0 commit comments

Comments
 (0)