我一直在寻找一个讨论是否有可能模仿html标签textarea在整个互联网上使用Monaco Editor的字段时调整大小,但我找不到回答我的问题。
我在React应用程序中使用monaco-editor npm包。您是否知道这是否易于实施?
解 使用纯css我选择了目标html元素并添加了以下属性:
div{
resize: vertical;
overflow: auto;
}
TL; DR:将automaticLayout: true
添加到编辑器的配置中。
点击;上:
Monaco有一个内置的自动调整大小到父容器功能:
反应> = 16.3.0(推荐)
constructor(props){super(props); this.ref = React.createRef();}
render(){
return <div ref={this.editorDiv} className="editor" ></div>
}
componentDidMount(){
let editor = monaco.editor.create(this.editorDiv.current, {
value: "var x = 0;",
language: 'javascript',
automaticLayout: true // the important part
});
}
反应<16.3.0
render(){
return <div ref={el=>{this.editorDiv = el}} className="editor" ></div>
}
// I use this configuration in the editor:
componentDidMount(){
let editor = monaco.editor.create(this.editorDiv, {
value: "var x = 0;",
language: 'javascript',
automaticLayout: true // the important part
});
}
编辑器的CSS(它避免了第一次像10px高度渲染编辑器):
.editor{
height: 100%;
}
摩纳哥版本:^ 0.10.1,最后测试:0.12.0
注意:该机制不听其容器大小的变化,它polls them。
如果您有对编辑器的引用,您可以在某些resize事件上调用editor.layout()
。窗口调整大小的示例
window.onresize = function (){
editor.layout();
};
希望这可以帮助。
在我的情况下,我正在使用那个确切的CSS,但虽然automaticLayout:true工作,我发现过度杀戮(似乎汇集DOM 100ms间隔,我在文档中打开了几个编辑器。所以我最终手动实现它:
为了以防万一,我的需求是不同的:我希望用户以标准方式调整容器大小,并在库和性能方面降低成本(包括代码和性能)。这就是我做的:
css容器:resize: vertical; overflow: auto
这个js:
function installResizeWatcher(el, fn, interval){
let offset = {width: el.offsetWidth, height: el.offsetHeight}
setInterval(()=>{
let newOffset = {width: el.offsetWidth, height: el.offsetHeight}
if(offset.height!=newOffset.height||offset.width!=newOffset.width){
offset = newOffset
fn()
}
}, interval)
}
const typeScriptCodeContainer = document.getElementById('typeScriptCodeContainer')
typeScriptCodeEditor = monaco.editor.create(typeScriptCodeContainer, Object.assign(editorOptions, {value: example.codeValue}))
installResizeWatcher(typeScriptCodeContainer, typeScriptCodeEditor.layout.bind(typeScriptCodeEditor), 2000)
是的,2秒间隔,并确保它只注册一次。我看到摩纳哥的自动重新布局有100ms的调整间隔 - 恕我直言,这太过分了。
看到它在行动:https://typescript-api-playground.glitch.me/?example=2
这是一个老问题,但得到问题并用react-resize-detector解决它
基于ResizeObserver它完全符合需要(检查browser compatibility)
组件示例:
import React, { Component } from 'react';
import ReactResizeDetector from 'react-resize-detector';
import * as monaco from 'monaco-editor';
class Editor extends Component {
constructor(props) {
super(props)
this.state = {
width: 0,
height: 0,
}
this.editor_div = React.createRef()
this.handle_rezise = this.handle_rezise.bind(this);
}
componentDidMount() {
const editor_model = monaco.editor.createModel('', 'sql');
this.monaco_editor = monaco.editor.create(this.editor_div.current, this.props.editorOptions);
this.monaco_editor.setModel(editor_model);
}
componentWillUnmount() {
this.monaco_editor && this.monaco_editor.dispose();
}
handle_rezise(width, height) {
this.monaco_editor.layout({ height, width });
}
render() {
return(
<div
className="editor-container"
style={{ height: '100%' }}>
<ReactResizeDetector
handleWidth
handleHeight
onResize={ this.handle_rezise }
refreshMode="debounce"
refreshRate={100} />
<div
className="editor"
ref={ this.editor_div }
style={{ height: '100%' }} />
</div>
)
}
}
export default Editor;
希望它有所帮助