在开发中具体运用场景如上图显示,在线编辑代码。
官方文档地址:microsoft.github.io/monaco-edit…
安装
npm install monaco-editor@0.30.1
vue3中具体使用
<div id="EditContainer" ref="EditContainer" style="height: 200px; width: 100%;"></div>
<script>
import { getCurrentInstance, onMounted } from 'vue'
import * as monaco from 'monaco-editor/esm/vs/editor/editor.main.js'
import 'monaco-editor/esm/vs/basic-languages/javascript/javascript.contribution'
import { parseSqlMetaData, createTips } from '@/views/utils/index.js'
export default {
name: "Demo",
setup() {
let monacoEditor = null;
let completionItemProvider = null;
const { proxy } = getCurrentInstance();
const handleCodeComplete = (fillDocument, monaco) => { // 创建代码提醒
completionItemProvider = monaco.languages.registerCompletionItemProvider('sql', {
provideCompletionItems: function(model, position) {
// find out if we are completing a property in the 'dependencies' object.
let suggestions = [];
let word = model.getWordUntilPosition(position);
suggestions = createTips(fillDocument, monaco, parseSqlMetaData(monacoEditor.getValue()));
return {suggestions: suggestions};
}
});
}
onMounted(() => {
// 获取自动补全内容
proxy.$axios.get('/data').then(({ data }) => {
let fillDocument = data.datas //拿到自定义的提示内容
// 创建代码提醒
handleCodeComplete(fillDocument, monaco)
})
monacoEditor = monaco.editor.create(proxy.$refs.EditContainer, {
value: '',
readOnly: false,
language: 'sql',
theme: 'vs-dark',
selectOnLineNumbers: true,
renderSideBySide: false,
});
})
return {
}
}
}
</script>
!!! 封装解析代码方法,如果需求没有这个要求的话,就不需要以下这堆方法
@/views/utils/index
export const createTips = (fillDocument, monaco, sqlMetaData) => {
const fillSql = fillDocument.map(x => ({
label: x.fillValue,
kind: monaco.languages.CompletionItemKind[x.category || 'Text'],
insertText: x.fillValue,
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
detail: x.description
}))
const sqlMetaDataSql = []
if (sqlMetaData.metaData && sqlMetaData.metaData.length) {
sqlMetaData?.metaData?.forEach((item) => {
sqlMetaDataSql.push({
label: item.table,
kind: monaco.languages.CompletionItemKind.Constant,
insertText: item.table,
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
detail: 'FlinkSQL Connector => ' + item.connector
});
item.columns.forEach((column) => {
sqlMetaDataSql.push({
label: column.name,
kind: monaco.languages.CompletionItemKind.Field,
insertText: column.name,
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
detail: 'Column => ' + column.type + ' from ' + item.table
});
})
})
}
const innerSql = [
/** * 内置函数 */
{
label: 'SUM(number)', //显示的提示名称
kind: monaco.languages.CompletionItemKind.Function, // 展示的类型
insertText: 'SUM(${1:})', //选择后粘贴到编辑器中的文字
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
detail: '返回指定参数的求和'
},
{
label: 'SQRT(number)',
kind: monaco.languages.CompletionItemKind.Function,
insertText: 'SQRT(${1:})',
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
detail: '返回指定参数的平方根'
},
{
label: 'SIN(number)',
kind: monaco.languages.CompletionItemKind.Function,
insertText: 'SIN(${1:})',
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
detail: '返回指定参数的正弦值'
},
{
label: 'SINH(number)',
kind: monaco.languages.CompletionItemKind.Function,
insertText: 'SINH(${1:})',
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
detail: '返回指定参数的双曲正弦值'
},
{
label: 'SIGN(number)',
kind: monaco.languages.CompletionItemKind.Function,
insertText: 'SIGN(${1:})',
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
detail: '返回指定参数的符合'
},
{
label: 'SUBSTRING(string,integer1,integer2)',
kind: monaco.languages.CompletionItemKind.Function,
insertText: 'SUBSTRING(${1:})',
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
detail: '返回指定字符串的子字符串'
},
]
return innerSql.concat(fillSql).concat(sqlMetaDataSql)
}
export const getStatements = (sql) => {
return sql.split(';');
}
export const parseSqlMetaData = (sql) => {
if(!sql||sql==='') {
return false;
}
sql = sql.replaceAll('\r\n','').replaceAll(',',' ,').replaceAll(/\s+/g,' ');
let statements = getStatements(sql);
let metaDatas = [];
for(let i in statements) {
if(!statements[i]||statements[i]==='') {
continue;
}
if(!/create\s+table/i.test(statements[i])) {
continue;
}
metaDatas.push(regMetaData(statements[i]));
}
return {
statement: sql,
metaData: metaDatas,
}
}
常用方法
1、monacoEditor.getValue()
获取editor内容,返回字符串,保留了所有信息换行、缩进、注释等。
2、monacoEditor.setValue()
更改editor内容,在实际开发中可用来实现回显功能。
3、monacoEditor.getSelection()
获取被选中的editor内容
4、monacoEditor.addAction()
自定义右键菜单