业务背景
因monaco-editor的键盘快捷键会与浏览器的键盘快捷键冲突,希望能够支持用户自行配置激活/禁用monaco-editor内置的键盘快捷键
思路
官方文档没有给出直接调用的API禁用全部键盘快捷键,也没有给出单个键盘快捷键的禁用方法。阅读monaco-editor的源码发现所有的actions和command都有其注册方法,但没有取消注册的方法。
失败的方案一:
直接将editor实例的_actions属性置空,那么editor.getActions()或editor.getSupportedActions()都返回空数组,看起来像是成功禁用键盘快捷键,但是运行"CTRL+F",发现依然能打开find 组件弹窗。
<template>
<div ref="monaco" :style="{'height': height, width: '100%'}"></div>
</template>
data() {
return {
editorOptions: {
contextmenu: true,
language: 'python',
theme: 'vs',
minimap: {
enabled: false
},
glyphMargin: false, //字形边缘
fontSize: 14, //字体大小
scrollBeyondLastLine: false, // 控制编辑器是否可以滚动到最后一样之后,置否,因为不想要无代码的空白页面
selectOnLineNumbers: true, // 单击行号时是否应选择相应的行,默认true
overviewRulerBorder: false, // 滚动条的边框
roundedSelection: false,
readOnly: false, // 只读
cursorStyle: 'line', //光标样式
automaticLayout: true, //自适应布局,编辑器将设置一个间隔时间来检查其dom节点大小是否已更改
useTabStops: false,
autoIndent: true, //自动布局
quickSuggestions: true,
lineNumbersMinChars: 5, // 控制行号的宽度,至少呈现一定数量的数字Defaults to 5.
lineDecorationsWidth: 10
}
}
}
mounted() {
this.editor = monaco.editor.create(this.$refs.monaco, this.editorOptions)
this.editor.onDidChangeModelContent(event => {
this.$emit('codeChange', this.editor.getValue())
})
this.editor._actions = {}
}
失败的方案二:
监听键盘的keydown事件,罗列出所有快捷键的组合,捕获事件,重写事件的回调函数,组织事件冒泡和默认行为。该方案成功禁用了键盘快捷键,但是代价是需要遍历143种快捷键组合,且需适配不同操作系统window/mac的键盘组合情况,费时费力。并且每一个注册、取消注册快捷键的回调函数,费时费力,不便于支持用户灵活配置。
mounted() {
this.editor = monaco.editor.create(this.$refs.monaco, this.editorOptions)
this.editor.onDidChangeModelContent(event => {
this.$emit('codeChange', this.editor.getValue())
})
this.editor.onKeyDown((listener, thisArgs, disposables) => {
if (listener.ctrlKey && listener.keyCode === 36) {
console.log(`按下了 ctrl + f`)
listener.stopPropagation()
listener.preventDefault()
}
})
}
成功的方案三:
需配置editor的options中的contextmenu项,当禁用情景菜单时,也不会触发monaco-editor的键盘快捷键,并且通过官方文档给出的api: updateOptions可以灵活的配置激活/禁用键盘快捷键
1. 在创建编辑器时定义一个
monaco.editor.create(document.getElementById("container"), {
value: "function hello() {\n\talert('Hello world!');\n}",
language: "javascript",
// ---------
contextmenu: false, // or set another keyCode here
})
2. 如果在运行时要启用/禁用
monaco.editor.updateOptions({
contextmenu: false;
});
在项目代码中改为
mounted() {
this.editor = monaco.editor.create(this.$refs.monaco, this.editorOptions)
this.editor.onDidChangeModelContent(event => {
this.$emit('codeChange', this.editor.getValue())
})
this.editor.updateOptions({
contextmenu: false;
})
}