可能不是摩纳哥特有的,但下面是演示该问题的示例。我有一个 Vue 3 应用程序,其状态是对象列表。该应用程序呈现多个包含 Monaco 编辑器实例的组件,我将每个状态对象传递给组件,并将该状态用作组件内的属性。我将命令附加到编辑器,在这种情况下,属性包含不正确的状态。它使用列表中的最后一个状态对象。使用示例可能会更清楚:
类型.ts
export type MyObj = {
code: string;
};
应用程序.vue
<script setup lang="ts">
import { ref } from 'vue';
import { type MyObj } from './components/types';
import CodeEditor from './components/CodeEditor.vue';
const myObjs = ref<MyObj[]>([
{ code: 'foo' },
{ code: 'bar' },
{ code: 'biz' },
])
</script>
<template>
<CodeEditor v-for="obj in myObjs" :obj="obj" :key="obj.code" />
</template>
代码编辑器.vue
<script setup lang="ts">
import { defineProps, onMounted, type PropType, ref } from 'vue';
import * as monaco from 'monaco-editor';
import type { MyObj } from './types';
const props = defineProps({
obj: {
type: Object as PropType<MyObj>,
required: true,
}
});
const editorContainer = ref<HTMLDivElement | null>(null);
onMounted(() => {
console.log('onMounted, code = ', props.obj.code);
if (!editorContainer.value) {
return;
}
const editor = monaco.editor.create(editorContainer.value, {
value: props.obj.code,
language: 'python',
automaticLayout: true,
});
editor.getModel()?.onDidChangeContent(() => {
console.log('Content changed, code = ', props.obj.code);
});
editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter, () => {
console.log('Cmd + Enter, code = ', props.obj.code);
});
});
</script>
<template>
<div ref="editorContainer" class="editor"></div>
</template>
<style>
.editor {
min-height: 100px;
border: 2px solid #ccc;
margin-bottom: 10px;
}
</style>
请注意,在此
CodeEditor
组件中,我附加了以下键盘命令(Cmd + Enter):
editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter, () => {
console.log('Cmd + Enter, code = ', props.obj.code);
})
这就是问题所在。
渲染应用程序时,如预期的那样,消息从
onMounted
记录为:
onMounted, code = foo
onMounted, code = bar
onMounted, code = biz
但是,当我从三个编辑器中的每一个执行键盘命令时,我得到:
Cmd + Enter, code = biz
Cmd + Enter, code = biz
Cmd + Enter, code = biz
其中,
biz
是列表中的最后一项。奇怪的是,请注意我还向编辑器附加了一个 onDidChangeContent
事件:
editor.getModel()?.onDidChangeContent(() => {
console.log('Content changed, code = ', props.obj.code);
});
当在三个编辑器中输入新角色时,按顺序,我从 props 中看到正确的代码:
Content changed, code = foo
Content changed, code = bar
Content changed, code = biz
任何帮助或推动正确的方向将不胜感激。谢谢。
对于那些偶然发现这个问题的人来说,这个问题似乎与 Monaco 有关,而不是 Vue。当同一页面上有多个编辑器实例时,在摩纳哥使用 addCommand
时会出现一个
open bug。上面的错误报告中的建议是,如果可能的话,使用操作作为解决方法。对于原始问题中的代码,使用操作,它将变成:
editor.addAction({
id: 'execute',
label: 'execute',
keybindings: [monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter],
run() {
console.log('Cmd + Enter, code = ', props.obj.code)
}
});
这似乎可以解决问题。