npm install monaco-editor -S
npm install sql-formatter -S
<template>
<div class="code-container" ref="container">
<slot></slot>
</div>
</template>
<script>
import * as monaco from "monaco-editor";
import sqlFormatter from "sql-formatter";
import { language as mysqlLanguage } from "monaco-editor/esm/vs/basic-languages/mysql/mysql.js";
export default {
props: {
code: {
type: String,
default: "",
},
},
data() {
return {
monacoEditor: {},
};
},
methods: {
// 初始化
init() {
this.monacoEditor = monaco.editor.create(this.$refs.container, {
value: this.code, // 代碼
readOnly: false, // 只讀
language: "mysql", // 語(yǔ)法
theme: "vs-dark", // 主題 vs/vs-dark/hc-black (可使用defineTheme中的主題)
folding: true, // 代碼折疊
position: true,
// showFoldingControls: "always",// 折疊圖標(biāo)顯示 mouseover/always
quickSuggestions: true, // 支持搜索 ctrl + F
automaticLayout: true, // resize自動(dòng)布局
cursorStyle: "line", // 光標(biāo)樣式 line/block/underline/line-thin/block-outline/underline-thin
roundedSelection: true, // 控制選區(qū)是否有圓角
});
},
// 右擊菜單項(xiàng) + 快捷鍵
addAction() {
// 格式化文檔(右擊菜單項(xiàng) + 快捷鍵)
this.fmtSql();
// 保存(快捷鍵)
this.save();
},
save() {
let that = this;
this.monacoEditor.addCommand(
monaco.KeyMod.CtrlCmd | monaco.KeyCode.KEY_S,
() => {
console.log("save");
console.log(`總行數(shù):${this.monacoEditor.getModel().getLineCount()}`);
console.log(`內(nèi)容打印:${that.monacoEditor.getValue()}`);
}
);
},
fmtSql() {
this.monacoEditor.addAction({
id: "formatDocument", // 菜單項(xiàng) id
label: "格式化文檔", // 菜單項(xiàng)名稱(chēng)
// 綁定快捷鍵
keybindings: [
monaco.KeyMod.CtrlCmd | monaco.KeyMod.Shift | monaco.KeyCode.KEY_F,
],
contextMenuGroupId: "formatDocument", // 所屬菜單的分組 //9_cutcopypaste
run: () => {
let sqlContent = sqlFormatter.format(this.monacoEditor.getValue());
this.replaceContent(sqlContent);
}, // 點(diǎn)擊后執(zhí)行的操作
});
},
// 修改內(nèi)容
replaceContent(text) {
this.monacoEditor.executeEdits("SELECT", [
{
range: {
startLineNumber: 0,
startColumn: 0,
endLineNumber: Infinity,
endColumn: Infinity,
},
text,
},
]);
},
// 注冊(cè)語(yǔ)法提示
registerMysql() {
monaco.languages.registerCompletionItemProvider("mysql", {
provideCompletionItems: function (model, position) {
var textUntilPosition = model.getValueInRange({
startLineNumber: position.lineNumber,
startColumn: 1,
endLineNumber: position.lineNumber,
endColumn: position.column,
});
var match = textUntilPosition.match(/(\S+)$/);
if (!match) return [];
match = match[0].toUpperCase();
var suggestions = [];
// 關(guān)鍵詞
mysqlLanguage.keywords.forEach((item) => {
if (item.indexOf(match) !== -1) {
suggestions.push({
label: item,
kind: monaco.languages.CompletionItemKind.Keyword,
insertText: item,
});
}
});
// 算法
mysqlLanguage.operators.forEach((item) => {
if (item.indexOf(match) !== -1) {
suggestions.push({
label: item,
kind: monaco.languages.CompletionItemKind.Operator,
insertText: item,
});
}
});
// 內(nèi)置函數(shù)
mysqlLanguage.builtinFunctions.forEach((item) => {
if (item.indexOf(match) !== -1) {
suggestions.push({
label: item,
kind: monaco.languages.CompletionItemKind.Function,
insertText: item,
});
}
});
return {
suggestions,
};
},
});
},
},
mounted() {
// 初始化
this.init();
this.addAction();
// monaco.editor.setTheme("dark");
// 注冊(cè)MySQL語(yǔ)法提示
this.registerMysql();
this.$nextTick(() => {
this.monacoEditor.setValue("SELECT * FROM `sys_table_config`"); // 設(shè)置默認(rèn)值
});
// 禁用默認(rèn)事件
/**
* ============================================================================
* (/^▽^)/
* EVENT LISTENER!
* ============================================================================
*/
// 實(shí)時(shí)更新
this.monacoEditor.onDidChangeModelContent(() => {
let value = this.monacoEditor.getValue();
this.$emit("change", value);
});
// 顯示行列
this.monacoEditor.onDidChangeCursorPosition((e) => {
console.log(`行 ${e.position.lineNumber}骇笔,列 ${e.position.column}`);
});
window.addEventListener("beforeunload", function (e) {
e.preventDefault();
e.returnValue = "Do you sure";
});
},
};
</script>
<style>
.code-container {
height: 100vh;
overflow: hidden;
}
</style>