内容简介:React Native + Visual Studio Code / Monaco Editor 制作手机编辑器
因为想为 Growth 3.0 (GitHub: https://github.com/phodal/growth-ng )里添加一个练习功能,便想要这样的话,就需要一个代码编辑器——是的,我又要定制一个编辑器了。能想到最简单的方案就是:基于 WebView。而,我想要大致的功能就是:
- 可以用 React Native 传递代码到 WebView 里
- 点击 React Native 上的按钮,就可以运行 WebView 里的代码
便想到了 VS Code 背后的 Monaco Editor,其架构师为大名鼎鼎的「GoF 设计模式」作者之一 Erich Gamma。
因此,我要做的无非就是:
- 集成 Monaco Editor
- 制定一个简单的代码运行机制、消息规范
- 处理一些特殊的函数,如 console.log
React Native 集成 Monaco Editor
这一步倒是比较简单:从官网下载一个 Demo 即可,然后按示例,配置一下就可以了:
require.config({paths: {'vs': './vs'}}); require(['vs/editor/editor.main'], function() { var editor = monaco.editor.create(document.getElementById('container'), { value: [ 'function x() {', '\tconsole.log("Hello world!");', '}' ].join('\n'), language: 'javascript' }); });
而,为了支持中文,则还需要加上几句代码:
require.config({ 'vs/nls' : { availableLanguages: { '*': 'zh-cn' } } });
然后在我们的 RN 代码中,引入这个 WebView 即可:
render = () => { let source; if (__DEV__) { source = require('./GrEditor/index.html'); } else { source = Platform.OS === 'ios' ? require('./GrEditor/index.html') : { uri: 'file:///android_asset/GrEditor/index.html' }; } return ( <WebView ref={(webview) => { this.webview = webview; EditorWebViewServices.setWebView(webview); }} startInLoadingState source={source} onMessage={this.handleMessage} automaticallyAdjustContentInsets={false} style={[AppStyles.container, styles.container, { height: this.state.visibleHeight }]} /> ); }
然后,我们就需要制定一个简单的代码运行机制。
RN 触发 Monaco Editor 事件
当我们在原生界面上点击运行时,我们只需要 postMessage 过去即可:
static runCode() { EditorWebViewServices.getWebView().postMessage(JSON.stringify({ action: 'runCode', code: {}, })); }
然后在 WebView 里处理对应的 Action:
document.addEventListener('message', function (event) { var data = JSON.parse(event.data); if(data.action === 'runCode') { eval(window.editor.getValue()); } });
这里的 window.editor.getValue()
可以获取到 Monaco Editor 中的代码,为了方便我就暂时直接用 eval 函数了,啊哈哈哈~~。
这样一来,代码勉强算是可以工作了。
React Native 与 Monaco Editor 处理 console.log
在测试的过程中,我发现了 console.log
是没有地方输出的,想自己定制一个 Console.log 界面,发现还挺麻烦的。于是,就想到了用 Toast 来显示——于是,我便在 WebView 里覆盖住了系统的 console.log,改成了直接 postMessage:
window.console.log = function(options) { var result = { action: 'console', data: options, }; window.postMessage(JSON.stringify(result)); };
而在 React Native 的组件里,则也是对数据进行对应的处理:
handleMessage = (event: Object) => { const message = JSON.parse(event.nativeEvent.data); if (message.action === 'console') { if (isObject(message.data)) { Toast.show(JSON.stringify(message.data)); } else { Toast.show(message.data.toString()); } } };
可这样,还是有个问题,我测试了一个 for 循环,结果发现只显示最后一个值。不过,我相信没有太多的用户会用它来写简单的代码。
React Native Monaco Editor 屏幕旋转
同理的,后来在处理屏幕也是相似的,在 RN 里监听屏幕旋转:
orientationDidChange = () => { EditorWebViewServices.getWebView().postMessage(JSON.stringify({ action: 'resize', })); };
然后在 WebView 里处理:
document.addEventListener('message', function (event) { var data = JSON.parse(event.data); if(data.action === 'runCode') { eval(window.editor.getValue()); } if(data.action === 'resize') { window.editor.layout(); } });
周末就这么过去了,有人要来一起填坑吗?
以上所述就是小编给大家介绍的《React Native + Visual Studio Code / Monaco Editor 制作手机编辑器》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 我做编辑器这些年:钉钉文档编辑器的前世今生
- 有爱编辑器 1.7.1 发布,mysql 编辑器 GUI
- 小书匠编辑器 6.0.0 发布,好用的 Markdown 编辑器
- 小书匠编辑器 6.0.0 发布,好用的 Markdown 编辑器
- 10个最佳富文本编辑器
- 在线代码编辑器利器-codeMirror
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。