vue使用monaco-editor编辑器,支持SQL、JSON、JS、HTML、CSS...等
json
适用于现代 C++ 的 JSON。
项目地址:https://gitcode.com/gh_mirrors/js/json
免费下载资源
·
使用 yarn add 或者 npm install 等命令均可,但是版本会有很大的影响,
monaco-editor 的版本与 monaco-editor-webpack-plugin 的版本有对应关系,如下
本项目使用的是
"monaco-editor": "^0.30.0",
"monaco-editor-webpack-plugin": "^6.0.0",
vue.config.js中配置
module.exports={
configureWebpack: {
plugins: [
new MonacoWebpackPlugin({
languages: ['sql', 'javascript', 'typescript', 'html', 'css', 'json', 'java'],
features: ["coreCommands", "find"]
})
]
}
}
封装组件
my-monaco-editor.vue
<template>
<div id="app" style="height: 80vh">
<div id="code-editor" ref="code-editor" style="height: 100%; width: 100%"></div>
</div>
</template>
<script>
import * as monaco from "monaco-editor";
import { language } from "monaco-editor/esm/vs/basic-languages/sql/sql";
// SQL语法校验
import { Parser } from 'node-sql-parser';
// SQL代码格式化
import { format } from 'sql-formatter';
// 从 monaco-editor 的 sql 里面拿到关键字
const { keywords } = language;
export default {
name: "App",
data() {
return {
// 编辑器实例
editor: null,
// 原本已经写入的数据
value: "SELECT * FROM users;SELECT * FROM roles;",
// 补全的数据,建议在编辑器初始化之间就请求回来放好
tables: {
users: ["name", "id", "email", "phone", "password"],
roles: ["id", "name", "order", "created_at", "updated_at", "deleted_at"]
},
// 编辑器主题
theme: "vs-dark", // 默认是 "vs"
};
},
mounted() {
// 建议在这里把表名和字段名先拿出来
// ....
// this.tables = res.data?.data
// 首先初始化
this.initAutoCompletion();
// 初始化编辑器
this.editor = monaco.editor.create(document.getElementById("code-editor"), {
value: this.value, // 初始文字
language: "sql", // 语言
readOnly: false, // 是否只读
automaticLayout: true, // 自动布局
disableLayerHinting: true,
theme: this.theme, // vs | hc-black | vs-dark
minimap: {
enabled: false,// 关闭小地图
},
// tabSize: 2, // tab缩进长度
fontSize: 14, // 文字大小
});
// 是否开启sql格式化
const formattedSQL = format(this.editor.getValue());
this.editor.setValue(formattedSQL);
// 监听编辑器内容变化
this.editor.onDidChangeModelContent(() => {
this.validateSQL(); // 在内容更改时进行语法验证
});
},
beforeDestroy() {
// 销毁之前把monaco的实例也销毁了,不然会多次注册
if (this.editor) {
this.editor.dispose();
}
},
methods: {
validateSQL() {
const value = this.editor.getValue();
const p = new Parser();
try {
p.astify(value); // 解析SQL语句
// 清除之前的错误标记
monaco.editor.setModelMarkers(this.editor.getModel(), 'sql', []);
} catch (error) {
const { line, column } = error.location.start;
// 创建错误标记
const marker = {
severity: monaco.MarkerSeverity.Error,
startLineNumber: line,
startColumn: column,
endLineNumber: line,
endColumn: column + 1,
message: error.message,
};
// 设置错误标记
monaco.editor.setModelMarkers(this.editor.getModel(), 'sql', [marker]);
}
},
/**
* @description: 获取编辑器中填写的值
*/
getValue() {
return this.editor.getValue();
},
/**
* @description: 初始化自动补全
*/
initAutoCompletion() {
monaco.languages.registerCompletionItemProvider("sql", {
// 触发提示的字符
triggerCharacters: [".", " ", ...keywords],
provideCompletionItems: (model, position) => {
let suggestions = [];
// 行号,列号
const { lineNumber, column } = position;
// 光标之前的所有字符,即从这一行的 0 到当前的字符
const textBeforePointer = model.getValueInRange({
startLineNumber: lineNumber,
startColumn: 0,
endLineNumber: lineNumber,
endColumn: column,
});
// trim() 取消两边空格,保证拆分出来前后都不是空值
// \s是指空白,包括空格、换行、tab缩进等所有的空白
const words = textBeforePointer.trim().split(/\s+/);
// 最后的一个有效词
const lastWord = words[words.length - 1];
if (lastWord.endsWith(".")) { // 如果这个词以 . 结尾,那么认为是希望补全表的字段
// 拿到真实的表名,把 . 去掉
const tableName = lastWord.slice(0, lastWord.length - 1);
if (Object.keys(this.tables).includes(tableName)) {
suggestions = [...this.getFieldsSuggest(tableName)];
}
} else if (lastWord === ".") {
// 如果这个词本身就是一个 . 即点前面是空的,那么什么都不用补全了
// 按理说这应该是个语法错误
suggestions = [];
} else {
// 其他时候都补全表名,以及关键字
suggestions = [...this.getTableSuggest(), ...this.getKeywordsSuggest()];
}
return {
suggestions,
};
},
});
},
/**
* @description: 获取关键字的补全列表
* @tips: CompletionItemKind 的所有枚举可以在monaco.d.ts 文件中找到,有二十多个,取需即可
*/
getKeywordsSuggest() {
return keywords.map((key) => ({
label: key,// 显示的名称
kind: monaco.languages.CompletionItemKind.Keyword,
insertText: key,// 真实补全的值
}));
},
/**
* @description: 获取表名的补全列表
*/
getTableSuggest() {
return Object.keys(this.tables).map((key) => ({
label: key, // 显示的名称
kind: monaco.languages.CompletionItemKind.Variable,
insertText: key, // 真实补全的值
}));
},
/**
* @description: 根据表名获取字段补全列表
* @param {*} tableName
*/
getFieldsSuggest(tableName) {
const fields = this.tables[tableName];
if (!fields) {
return [];
}
return fields.map((name) => ({
label: name,
kind: monaco.languages.CompletionItemKind.Field,
insertText: name,
}));
},
}
};
</script>
<style>
.sql-error-decoration {
border-bottom: 1px solid red;
}
</style>
组件内使用
<template>
<div>
<monaco-edito ref="js"></monaco-edito>
<div>
<!-- <button @click="runCode">运行</button> -->
</div>
</div>
</template>
<script>
import MonacoEdito from "@/components/my-monaco-editor.vue";
export default {
components: {
MonacoEdito,
},
methods: {
runCode() {
var js = this.$refs.js.monacoEditor.getValue();
console.log(js);
},
},
};
</script>
<style lang="scss" scoped>
</style>
GitHub 加速计划 / js / json
41.72 K
6.61 K
下载
适用于现代 C++ 的 JSON。
最近提交(Master分支:1 个月前 )
960b763e
4 个月前
8c391e04
6 个月前
更多推荐
已为社区贡献1条内容
所有评论(0)