npm install monaco-editor -S
npm install sql-formatter -S
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", // 语法
theme: "vs-dark", // 主题 vs/vs-dark/hc-black (可使用defineTheme中的主题)
folding: true, // 代码折叠
position: true,
// showFoldingControls: "always",// 折叠图标显示 mouseover/always
quickSuggestions: true, // 支持搜索 ctrl + F
automaticLayout: true, // resize自动布局
cursorStyle: "line", // 光标样式 line/block/underline/line-thin/block-outline/underline-thin
roundedSelection: true, // 控制选区是否有圆角
});
},
// 右击菜单项 + 快捷键
addAction() {
// 格式化文档(右击菜单项 + 快捷键)
this.fmtSql();
// 保存(快捷键)
this.save();
},
save() {
let that = this;
this.monacoEditor.addCommand(
monaco.KeyMod.CtrlCmd | monaco.KeyCode.KEY_S,
() => {
console.log("save");
console.log(`总行数:${this.monacoEditor.getModel().getLineCount()}`);
console.log(`内容打印:${that.monacoEditor.getValue()}`);
}
);
},
fmtSql() {
this.monacoEditor.addAction({
id: "formatDocument", // 菜单项 id
label: "格式化文档", // 菜单项名称
// 绑定快捷键
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);
}, // 点击后执行的操作
});
},
// 修改内容
replaceContent(text) {
this.monacoEditor.executeEdits("SELECT", [
{
range: {
startLineNumber: 0,
startColumn: 0,
endLineNumber: Infinity,
endColumn: Infinity,
},
text,
},
]);
},
// 注册语法提示
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 = [];
// 关键词
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,
});
}
});
// 内置函数
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");
// 注册MySQL语法提示
this.registerMysql();
this.$nextTick(() => {
this.monacoEditor.setValue("SELECT * FROM `sys_table_config`"); // 设置默认值
});
// 禁用默认事件
/**
* ============================================================================
* (/^▽^)/
* EVENT LISTENER!
* ============================================================================
*/
// 实时更新
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";
});
},
};
.code-container {
height: 100vh;
overflow: hidden;
}