vue中实现Monaco Editor自定义提示功能


Posted in Javascript onJuly 05, 2019

这次接到一个需求,要在浏览器的 IDE 中支持自定义提示功能,如下所示:

vue中实现Monaco Editor自定义提示功能

可以看到,它可以根据用户输入的内容来一项一项排除,只显示完全匹配的那一项。

项目的框架是 Vue ,编辑器用的是 Monaco Editor

什么是 Monaco Editor

vscode 是我们经常在用的编辑器,它的前身是微软的一个叫 Monaco Workbench 的项目,而 Monaco Editor 就是从这个项目中成长出来的一个 web 编辑器,他们很大一部分的代码都是共用的,所以 Monaco EditorVSCode 在编辑代码,交互及 UI 上几乎是一摸一样的。不同的是,两者的平台不一样, Monaco Editor 基于浏览器,而 VSCode 基于 electron ,所以功能上 VSCode 更加健全,性能比较强大。

用法

安装

npm install monaco-editor --save

使用

<div id="monaco" class="monaco-editor"></div>
import * as monaco from 'monaco-editor';
this.fileEditor = this.monaco.editor.create(document.getElementById('monaco'), {
 value: null,
 language: 'sql' // 这里以sql为例
})

this.fileEditor.dispose(); // 使用完后销毁

这里引入 monaco 要注意,在 react 中以下面方式引入:

import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';

实现自定义提示功能

查看了资料后,发现在 monaco 中有提供一个提示功能的方法 registerCompletionItemProvider ,具体实现如下:

this.monaco.languages.registerCompletionItemProvider('sql', { // 这里以sql语言为例
 provideCompletionItems () {
  return [{
   label: '${_DB', // 显示的提示内容
   kind: this.monaco.languages.CompletionItemKind['Function'], // 用来显示提示内容后的不同的图标
   insertText: '{_DB', // 选择后粘贴到编辑器中的文字
   detail: '' // 提示内容后的说明
  }];
 },
 triggerCharacters: ['$'] // 触发提示的字符,可以写多个
});

以上的用法,我试了一下之后发现,虽然 triggerCharacters 的值是数组,可以有多个,但是里面的字符串只能识别一个字符。一开始的需求是输入 ${_ 之后提示 ${_DB ,但是由于不能识别多个字符,只能做到出现 $ 就提示。

还有一个问题就是 registerCompletionItemProvider 的第一个参数只能是字符串,如果有多种语言只能叠加重复写,恰巧我的需求是有多种语言,所以只能如下解决,也就是每种语言都写了一遍:

['json', 'yaml', 'php', 'go', 'sql', 'java', 'markdown', 'plaintext'].map(item => {
 this.monaco.languages.registerCompletionItemProvider(item, {
  provideCompletionItems () {
   return [{
    label: '${_DB',
    kind: this.monaco.languages.CompletionItemKind['Function'],
    insertText: '{_DB',
    detail: ''
   }];
  },
  triggerCharacters: ['$']
 });
});

需求是 ${_DB:key:value ,也就是说在输入 ${_DB 后,再输入一个 : 提示出 key ,在 key 之后输入 : 提示 value

这里又碰到一个问题,需要知道当前输入的内容来判断是 $ 还是 : ,而且后面两个触发提示的符号同是 : ,无法区分,只能通过识别 : 的位置来判断是提示 key 还是 value ,所以还要知道当前输入的 : 之前的内容。

那么只有在 provideCompletionItems 这一步判断,但是查遍了资料没有发现这样的参数, provideCompletionItems 只有 modelpositiontoken 这几个参数,后来发现 model 中的 getLineContent 方法可以获取指定行的所有内容,而 position 可以获取当前输入行的行数和列数,于是就有了以下解决方法:

this.monaco.languages.registerCompletionItemProvider(item, {
 provideCompletionItems (model, position) {
  // 获取当前行数
  const line = position.lineNumber
  
  // 获取当前列数
  const column = position.column
  
  // 获取当前输入行的所有内容
  const content = model.getLineContent(line)
  
  // 通过下标来获取当前光标后一个内容,即为刚输入的内容
  const sym = content[column - 2]
  
  if (sym === '$') {
   return [{
    label: '${_DB',
    kind: this.monaco.languages.CompletionItemKind['Function'],
    insertText: '{_DB',
    detail: ''
   }];
  }
  
  return [{
   label: ':abb',
   kind: this.monaco.languages.CompletionItemKind['Function'],
   insertText: 'abb',
   detail: ''
  },
  {
   label: ':bc',
   kind: this.monaco.languages.CompletionItemKind['Function'],
   insertText: 'bc',
   detail: ''
  }];
 },
 triggerCharacters: ['$', ':']
});

能获取光标后的第一个内容,后面的内容就都能获取啦,如果识别到前面的内容是 ${_DB 就提示 key ,否则提示 value

最后总结下来就是一定要多看文档,勤于测试就能解决问题啦~

总结

以上所述是小编给大家介绍的vue中实现Monaco Editor自定义提示功能 ,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Javascript 相关文章推荐
瀑布流布局代码一例
Apr 11 Javascript
jQuery 写的简单打字游戏可以提示正确和错误的次数
Jul 01 Javascript
jQuery实现的图片轮播效果完整示例
Sep 12 Javascript
Javascript中call,apply,bind方法的详解与总结
Dec 12 Javascript
利用Bootstrap实现表格复选框checkbox全选
Dec 21 Javascript
es6在react中的应用代码解析
Nov 08 Javascript
利用nginx + node在阿里云部署https的步骤详解
Dec 19 Javascript
全站最详细的Vuex教程
Apr 13 Javascript
在vue中读取本地Json文件的方法
Sep 06 Javascript
基于Node.js搭建hexo博客过程详解
Jun 25 Javascript
vue实现动态给id赋值,点击事件获取当前点击的元素的id操作
Nov 09 Javascript
JS 4个超级实用的小技巧 提升开发效率
Oct 05 Javascript
VueCli3.0中集成MockApi的方法示例
Jul 05 #Javascript
Electron vue的使用教程图文详解
Jul 05 #Javascript
监控微信小程序中的慢HTTP请求过程详解
Jul 05 #Javascript
JS实现求字符串中出现最多次数的字符和次数示例
Jul 05 #Javascript
JS Math对象与Math方法实例小结
Jul 05 #Javascript
js字符串类型String常用操作实例总结
Jul 05 #Javascript
JS前端知识点总结之内置对象,日期对象和定时器相关操作
Jul 05 #Javascript
You might like
escape unescape的php下的实现方法
2007/04/27 PHP
php中hashtable实现示例分享
2014/02/13 PHP
PHP函数超时处理方法
2016/02/14 PHP
php实现支持中文的文件下载功能示例
2017/08/30 PHP
PHP pthreads v3下worker和pool的使用方法示例
2020/02/21 PHP
js关于精确计算和数值格式化以及直接引js文件
2014/01/28 Javascript
JS控制div跳转到指定的位置的几种解决方案总结
2016/11/05 Javascript
Node.js中看JavaScript的引用
2017/04/22 Javascript
JavaScript编程设计模式之构造器模式实例分析
2017/10/25 Javascript
详解vue+css3做交互特效的方法
2017/11/20 Javascript
浅析vue 函数配置项watch及函数 $watch 源码分享
2018/11/22 Javascript
微信小程序vant弹窗组件的实现方式
2020/02/21 Javascript
mpvue网易云短信接口实现小程序短信登录的示例代码
2020/04/03 Javascript
JavaScript装箱及拆箱boxing及unBoxing用法解析
2020/06/15 Javascript
vue中的v-model原理,与组件自定义v-model详解
2020/08/04 Javascript
[01:00:06]加油DOTA_EP01_网络版
2014/08/09 DOTA
[39:07]LGD vs VP 2018国际邀请赛淘汰赛BO3 第二场 8.21
2018/08/22 DOTA
实现python版本的按任意键继续/退出
2016/09/26 Python
Python、PyCharm安装及使用方法(Mac版)详解
2017/04/28 Python
python3实现TCP协议的简单服务器和客户端案例(分享)
2017/06/14 Python
python绘制多个曲线的折线图
2020/03/23 Python
解决Python中定时任务线程无法自动退出的问题
2019/02/18 Python
利用Python半自动化生成Nessus报告的方法
2019/03/19 Python
python实现PID算法及测试的例子
2019/08/08 Python
Pandas 解决dataframe的一列进行向下顺移问题
2019/12/27 Python
Tensorflow之MNIST CNN实现并保存、加载模型
2020/06/17 Python
python与pycharm有何区别
2020/07/01 Python
英国门把手公司:Door Handle Company
2019/05/12 全球购物
战友聚会邀请函
2014/01/18 职场文书
学校运动会广播稿100条
2014/09/14 职场文书
2015年复活节活动总结
2015/02/27 职场文书
2015初一年级组工作总结
2015/07/24 职场文书
PHP对接阿里云虚拟号的实现(号码隐私保护)
2021/04/06 PHP
利用Java设置Word文本框中的文字旋转方向的实现方法
2021/06/28 Java/Android
mysql sock 文件解析及作用讲解
2022/07/15 MySQL
ubuntu开机后ROS程序自启动问题
2022/12/24 Servers