vue中實(shí)現(xiàn)Monaco Editor自定義提示功能
這次接到一個(gè)需求,要在瀏覽器的 IDE 中支持自定義提示功能,如下所示:

可以看到,它可以根據(jù)用戶輸入的內(nèi)容來(lái)一項(xiàng)一項(xiàng)排除,只顯示完全匹配的那一項(xiàng)。
項(xiàng)目的框架是 Vue ,編輯器用的是 Monaco Editor 。
什么是 Monaco Editor
vscode 是我們經(jīng)常在用的編輯器,它的前身是微軟的一個(gè)叫 Monaco Workbench 的項(xiàng)目,而 Monaco Editor 就是從這個(gè)項(xiàng)目中成長(zhǎng)出來(lái)的一個(gè) web 編輯器,他們很大一部分的代碼都是共用的,所以 Monaco Editor 和 VSCode 在編輯代碼,交互及 UI 上幾乎是一摸一樣的。不同的是,兩者的平臺(tái)不一樣, Monaco Editor 基于瀏覽器,而 VSCode 基于 electron ,所以功能上 VSCode 更加健全,性能比較強(qiáng)大。
用法
安裝
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';
實(shí)現(xiàn)自定義提示功能
查看了資料后,發(fā)現(xiàn)在 monaco 中有提供一個(gè)提示功能的方法 registerCompletionItemProvider ,具體實(shí)現(xiàn)如下:
this.monaco.languages.registerCompletionItemProvider('sql', { // 這里以sql語(yǔ)言為例
provideCompletionItems () {
return [{
label: '${_DB', // 顯示的提示內(nèi)容
kind: this.monaco.languages.CompletionItemKind['Function'], // 用來(lái)顯示提示內(nèi)容后的不同的圖標(biāo)
insertText: '{_DB', // 選擇后粘貼到編輯器中的文字
detail: '' // 提示內(nèi)容后的說(shuō)明
}];
},
triggerCharacters: ['$'] // 觸發(fā)提示的字符,可以寫多個(gè)
});
以上的用法,我試了一下之后發(fā)現(xiàn),雖然 triggerCharacters 的值是數(shù)組,可以有多個(gè),但是里面的字符串只能識(shí)別一個(gè)字符。一開始的需求是輸入 ${_ 之后提示 ${_DB ,但是由于不能識(shí)別多個(gè)字符,只能做到出現(xiàn) $ 就提示。
還有一個(gè)問(wèn)題就是 registerCompletionItemProvider 的第一個(gè)參數(shù)只能是字符串,如果有多種語(yǔ)言只能疊加重復(fù)寫,恰巧我的需求是有多種語(yǔ)言,所以只能如下解決,也就是每種語(yǔ)言都寫了一遍:
['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 ,也就是說(shuō)在輸入 ${_DB 后,再輸入一個(gè) : 提示出 key ,在 key 之后輸入 : 提示 value 。
這里又碰到一個(gè)問(wèn)題,需要知道當(dāng)前輸入的內(nèi)容來(lái)判斷是 $ 還是 : ,而且后面兩個(gè)觸發(fā)提示的符號(hào)同是 : ,無(wú)法區(qū)分,只能通過(guò)識(shí)別 : 的位置來(lái)判斷是提示 key 還是 value ,所以還要知道當(dāng)前輸入的 : 之前的內(nèi)容。
那么只有在 provideCompletionItems 這一步判斷,但是查遍了資料沒有發(fā)現(xiàn)這樣的參數(shù), provideCompletionItems 只有 model 、 position 、 token 這幾個(gè)參數(shù),后來(lái)發(fā)現(xiàn) model 中的 getLineContent 方法可以獲取指定行的所有內(nèi)容,而 position 可以獲取當(dāng)前輸入行的行數(shù)和列數(shù),于是就有了以下解決方法:
this.monaco.languages.registerCompletionItemProvider(item, {
provideCompletionItems (model, position) {
// 獲取當(dāng)前行數(shù)
const line = position.lineNumber
// 獲取當(dāng)前列數(shù)
const column = position.column
// 獲取當(dāng)前輸入行的所有內(nèi)容
const content = model.getLineContent(line)
// 通過(guò)下標(biāo)來(lái)獲取當(dāng)前光標(biāo)后一個(gè)內(nèi)容,即為剛輸入的內(nèi)容
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: ['$', ':']
});
能獲取光標(biāo)后的第一個(gè)內(nèi)容,后面的內(nèi)容就都能獲取啦,如果識(shí)別到前面的內(nèi)容是 ${_DB 就提示 key ,否則提示 value 。
最后總結(jié)下來(lái)就是一定要多看文檔,勤于測(cè)試就能解決問(wèn)題啦~
總結(jié)
以上所述是小編給大家介紹的vue中實(shí)現(xiàn)Monaco Editor自定義提示功能 ,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
如果你覺得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!
相關(guān)文章
一個(gè)因@click.stop引發(fā)的bug的解決
這篇文章主要介紹了一個(gè)因@click.stop引發(fā)的bug的解決,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-01-01
vue3使用Electron打包成exe的方法與打包報(bào)錯(cuò)解決
在前端開發(fā)中,Electron是一種常用的工具,它允許開發(fā)者使用Web技術(shù)構(gòu)建桌面應(yīng)用程序,本文主要介紹了vue3使用Electron打包成exe的方法與打包報(bào)錯(cuò)解決,具有一定的參考價(jià)值,感興趣的可以了解一下2024-06-06
Vue中mintui的field實(shí)現(xiàn)blur和focus事件的方法
今天小編就為大家分享一篇Vue中mintui的field實(shí)現(xiàn)blur和focus事件的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-08-08
vue3 setup點(diǎn)擊跳轉(zhuǎn)頁(yè)面的實(shí)現(xiàn)示例
本文主要介紹了vue3 setup點(diǎn)擊跳轉(zhuǎn)頁(yè)面的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-10-10
在vue2.x里面簡(jiǎn)單使用socketio問(wèn)題
這篇文章主要介紹了在vue2.x里面簡(jiǎn)單使用socketio問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10
vue 綁定使用 touchstart touchmove touchend解析
這篇文章主要介紹了vue 綁定使用 touchstart touchmove touchend解析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03
Taro+vue3?實(shí)現(xiàn)電影切換列表功能
我們做類似于貓眼電影的小程序或者H5?的時(shí)候?我們會(huì)做到那種?左右滑動(dòng)的電影列表,這種列表一般帶有電影場(chǎng)次,我這個(gè)項(xiàng)目是基于Taro?+vue3?+ts?來(lái)寫的用的組件庫(kù)也是京東的nut-ui以上的代碼和組件也有的是我二次封裝的組件,對(duì)vue3電影切換列表知識(shí),感興趣的朋友一起看看吧2024-01-01
vue監(jiān)聽瀏覽器的后退和刷新事件,阻止默認(rèn)的事件方式
這篇文章主要介紹了vue監(jiān)聽瀏覽器的后退和刷新事件,阻止默認(rèn)的事件方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10
vue實(shí)現(xiàn)計(jì)數(shù)器簡(jiǎn)單制作
這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)計(jì)數(shù)器簡(jiǎn)單制作,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-06-06

