如何构建Monaco Editor SQL代码提示编辑器实例的详细教程?

2026-03-31 18:111阅读0评论SEO基础
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1995个文字,预计阅读时间需要8分钟。

如何构建Monaco Editor SQL代码提示编辑器实例的详细教程?

目录+安装+简易+SQL+编辑器+相关功能+获取选中代码+替换选中代码+处理光标位置+自定义+SQL+库表提示,保留原有+SQL+提示+编辑器+resize+编辑器设置+主题+SQL+代码格式化+右键菜单汉化+记事本

目录
  • 安装
  • 简易 SQL 编辑器
  • 相关功能
    • 获取选中代码
    • 替换选中代码
    • 处理光标位置
    • 自定义 SQL 库表提示,并保留原有 SQL 提示
    • 编辑器 resize
    • 编辑器设置主题
    • SQL 代码格式化
    • 右键菜单汉化
    • 记得销毁编辑器对象哦
  • 踩坑
    • 如何快速去看懂 Monaco Editor

      安装

      安装依赖,这里请注意版本

      yarn add monaco-editor@0.29.1 yarn add monaco-editor-webpack-plugin@5.0.0

      配置 webpack 插件

      // vue.config.js ... const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin') module.export = { ... configureWebpack: { name: name, resolve: { alias: { '@': resolve('src'), }, }, plugins: [new MonacoWebpackPlugin()], }, ... }

      请注意 monaco-editor-webpack-plugin 和 monaco-editor 的对应关系,否则可能会出现无法运行的情况。

      monaco-editor-webpack-pluginmonaco-editor7.*.*>= 0.31.06.*.*0.30.*5.*.*0.29.*4.*.*0.25.*,0.26.*,0.27.*,0.28.*3.*.*0.22.*,0.23.*,0.24.*2.*.*0.21.*1.9.*0.20.*1.8.*0.19.*1.7.*0.18.*

      简易 SQL 编辑器

      先上干货!

      <template> <div ref="codeContainer" class="editor-container" :style="{ height: height + 'px' }" /> </template> <script> import * as monaco from 'monaco-editor' /** * VS Code 编辑器 * * 通过 getEditorVal 函数向外传递编辑器即时内容 * 通过 initValue 用于初始化编辑器内容。 * 编辑器默认 sql 语言,支持的语言请参考 node_modules\monaco-editor\esm\vs\basic-languages 目录下~ * 编辑器样式仅有 'vs', 'vs-dark', 'hc-black' 三种 */ export default { name: 'MonacoEditor', props: { initValue: { type: String, default: '', }, readOnly: Boolean, language: { type: String, default: 'sql', }, height: { type: Number, default: 300, }, theme: { type: String, default: 'vs', }, }, data() { return { monacoEditor: null, // 语言编辑器 } }, computed: { inputVal() { return this.monacoEditor?.getValue() }, }, watch: { inputVal() { if (this.monacoEditor) { this.$emit('change', this.monacoEditor.getValue()) } }, theme() { this.setTheme(this.theme) }, height() { this.layout() }, }, mounted() { this.initEditor() }, beforeDestroy() { if (this.monacoEditor) { this.monacoEditor.dispose() } }, methods: { initEditor() { if (this.$refs.codeContainer) { this.registerCompletion() // 初始化编辑器,确保dom已经渲染 this.monacoEditor = monaco.editor.create(this.$refs.codeContainer, { value: '', // 编辑器初始显示文字 language: 'sql', // 语言 readOnly: this.readOnly, // 是否只读 Defaults to false | true automaticLayout: true, // 自动布局 theme: this.theme, // 官方自带三种主题vs, hc-black, or vs-dark minimap: { // 关闭小地图 enabled: false, }, tabSize: 2, // tab缩进长度 }) } this.setInitValue() }, focus() { this.monacoEditor.focus() }, layout() { this.monacoEditor.layout() }, getValue() { return this.monacoEditor.getValue() }, // 将 initValue Property 同步到编辑器中 setInitValue() { this.monacoEditor.setValue(this.initValue) }, setTheme() { monaco.editor.setTheme(this.theme) }, getSelectionVal() { const selection = this.monacoEditor.getSelection() // 获取光标选中的值 const { startLineNumber, endLineNumber, startColumn, endColumn } = selection const model = this.monacoEditor.getModel() return model.getValueInRange({ startLineNumber, startColumn, endLineNumber, endColumn, }) }, setPosition(column, lineNumber) { this.monacoEditor.setPosition({ column, lineNumber }) }, getPosition() { return this.monacoEditor.getPosition() }, }, } </script> <style lang="scss" scoped></style>

      相关功能

      获取选中代码

      getSelectionVal() { const selection = this.monacoEditor.getSelection() // 获取光标选中的值 const { startLineNumber, endLineNumber, startColumn, endColumn } = selection const model = this.monacoEditor.getModel() return model.getValueInRange({ startLineNumber, startColumn, endLineNumber, endColumn, }) },

      如何构建Monaco Editor SQL代码提示编辑器实例的详细教程?

      替换选中代码

      insertStringInTemplate(str) { const selection = this.monacoEditor.getSelection() // 获取光标选中的值 const { startLineNumber, endLineNumber, startColumn, endColumn } = selection const model = this.monacoEditor.getModel() const textBeforeSelection = model.getValueInRange({ startLineNumber: 1, startColumn: 0, endLineNumber: startLineNumber, endColumn: startColumn, }) const textAfterSelection = model.getValueInRange({ startLineNumber: endLineNumber, startColumn: endColumn, endLineNumber: model.getLineCount(), endColumn: model.getLineMaxColumn(model.getLineCount()), }) this.monacoEditor.setValue(textBeforeSelection + str + textAfterSelection) this.monacoEditor.focus() this.monacoEditor.setPosition({ lineNumber: startLineNumber, column: startColumn + str.length, }) },

      处理光标位置

      setPosition(column, lineNumber) { this.monacoEditor.setPosition({ column, lineNumber }) }, getPosition() { return this.monacoEditor.getPosition() },

      自定义 SQL 库表提示,并保留原有 SQL 提示

      首先由后端提供具体的库表信息:

      export const hintData = { adbs: ['dim_realtime_recharge_paycfg_range', 'dim_realtime_recharge_range'], dimi: ['ads_adid', 'ads_spec_adid_category'], }

      然后根据已有库表信息进行自定义 AutoComplete

      import * as monaco from 'monaco-editor' import { language } from 'monaco-editor/esm/vs/basic-languages/sql/sql' const { keywords } = language export default { ... mounted() { this.initEditor() }, methods: { ... registerCompletion() { const _that = this monaco.languages.registerCompletionItemProvider('sql', { triggerCharacters: ['.', ...keywords], provideCompletionItems: (model, position) => { let suggestions = [] const { lineNumber, column } = position const textBeforePointer = model.getValueInRange({ startLineNumber: lineNumber, startColumn: 0, endLineNumber: lineNumber, endColumn: column, }) const tokens = textBeforePointer.trim().split(/\s+/) const lastToken = tokens[tokens.length - 1] // 获取最后一段非空字符串 if (lastToken.endsWith('.')) { const tokenNoDot = lastToken.slice(0, lastToken.length - 1) if (Object.keys(_that.hintData).includes(tokenNoDot)) { suggestions = [..._that.getTableSuggest(tokenNoDot)] } } else if (lastToken === '.') { suggestions = [] } else { suggestions = [..._that.getDBSuggest(), ..._that.getSQLSuggest()] } return { suggestions, } }, }) }, // 获取 SQL 语法提示 getSQLSuggest() { return keywords.map((key) => ({ label: key, kind: monaco.languages.CompletionItemKind.Enum, insertText: key, })) }, getDBSuggest() { return Object.keys(this.hintData).map((key) => ({ label: key, kind: monaco.languages.CompletionItemKind.Constant, insertText: key, })) }, getTableSuggest(dbName) { const tableNames = this.hintData[dbName] if (!tableNames) { return [] } return tableNames.map((name) => ({ label: name, kind: monaco.languages.CompletionItemKind.Constant, insertText: name, })) }, initEditor() { if (this.$refs.codeContainer) { this.registerCompletion() // 初始化编辑器,确保dom已经渲染 this.monacoEditor = monaco.editor.create(this.$refs.codeContainer, { value: '', // 编辑器初始显示文字 language: 'sql', // 语言 readOnly: this.readOnly, // 是否只读 Defaults to false | true automaticLayout: true, // 自动布局 theme: this.theme, // 官方自带三种主题vs, hc-black, or vs-dark minimap: { // 关闭小地图 enabled: false, }, tabSize: 2, // tab缩进长度 }) } this.setValue(this.value) }, } }

      编辑器 resize

      resize() { this.monacoEditor.layout() },

      编辑器设置主题

      注意!设置主题并非在编辑器实例上修改的哦!

      setTheme() { monaco.editor.setTheme(this.theme) },

      SQL 代码格式化

      编辑器自身不支持 sql 格式化(试了下 JavaScript 是支持的),所以用到了 sql-formatter 这个库。

      import { format } from 'sql-formatter' ... format() { this.monacoEditor.setValue( format(this.monacoEditor.getValue(), { indentStyle: 'tabularLeft', }), ) }, ...

      右键菜单汉化

      需要安装以下两个库

      npm install monaco-editor-nls --save npm install monaco-editor-esm-webpack-plugin --save-dev

      具体用法可以直接去 www.npmjs.com/package/mon… 里面看,我就不搬运了~

      记得销毁编辑器对象哦

      beforeDestroy() { if (this.monacoEditor) { this.monacoEditor.dispose() } },

      踩坑

      下面是我遇到的几个坑。

      • 最新版本的 Monaco Editor 已经使用了 ES2022 的语法,所以老项目可能会出现编译不过的问题。所以我把版本调低了一些。
      • 在最初调试编辑器的时候出现了无法编辑的情况,后来发现是同事用到了 default-passive-events 这个库来关闭 chrome 的 Added non-passive event listener to a scroll-blocking <some> event. Consider marking event handler as 'passive' to make the page more responsive 警告。结果拦截一些 event。

      如何快速去看懂 Monaco Editor

      一开始我看它的官方文档是非常懵的,各种接口、函数、对象的定义,完全不像是个前端库那么好理解。鼓捣了好久才慢慢找到门路。

      • 先看示例
        • 查看它的 playground,上面其实是有一些功能可以直接找到的。
        • 查看它在 github 上的 /samples 目录,里面也有不少示例。
        • 去掘金这类网站上找别人写的示例,能有不少启发。
      • 再看 API
        • 了解了自己所需要的功能相关的代码,再去看它文档的 API 就会发现容易理解多了。逐步发散理解更多关联功能。

      参考资料

      • 官方文档

      microsoft.github.io/monaco-edit…

      相关库

      Monaco Editor www.npmjs.com/package/mon…

      右键菜单汉化 www.npmjs.com/package/mon…

      webpack 插件 www.npmjs.com/package/mon…

      汉化 webpack 插件 www.npmjs.com/package/mon…

      SQL 代码格式化 www.npmjs.com/package/sql…

      博客

      www.jb51.net/article/258307.htm

      www.jb51.net/article/258269.htm

      以上就是Monaco Editor开发SQL编辑器实例详解的详细内容,更多关于Monaco Editor开发SQL编辑器的资料请关注易盾网络其它相关文章!

      本文共计1995个文字,预计阅读时间需要8分钟。

      如何构建Monaco Editor SQL代码提示编辑器实例的详细教程?

      目录+安装+简易+SQL+编辑器+相关功能+获取选中代码+替换选中代码+处理光标位置+自定义+SQL+库表提示,保留原有+SQL+提示+编辑器+resize+编辑器设置+主题+SQL+代码格式化+右键菜单汉化+记事本

      目录
      • 安装
      • 简易 SQL 编辑器
      • 相关功能
        • 获取选中代码
        • 替换选中代码
        • 处理光标位置
        • 自定义 SQL 库表提示,并保留原有 SQL 提示
        • 编辑器 resize
        • 编辑器设置主题
        • SQL 代码格式化
        • 右键菜单汉化
        • 记得销毁编辑器对象哦
      • 踩坑
        • 如何快速去看懂 Monaco Editor

          安装

          安装依赖,这里请注意版本

          yarn add monaco-editor@0.29.1 yarn add monaco-editor-webpack-plugin@5.0.0

          配置 webpack 插件

          // vue.config.js ... const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin') module.export = { ... configureWebpack: { name: name, resolve: { alias: { '@': resolve('src'), }, }, plugins: [new MonacoWebpackPlugin()], }, ... }

          请注意 monaco-editor-webpack-plugin 和 monaco-editor 的对应关系,否则可能会出现无法运行的情况。

          monaco-editor-webpack-pluginmonaco-editor7.*.*>= 0.31.06.*.*0.30.*5.*.*0.29.*4.*.*0.25.*,0.26.*,0.27.*,0.28.*3.*.*0.22.*,0.23.*,0.24.*2.*.*0.21.*1.9.*0.20.*1.8.*0.19.*1.7.*0.18.*

          简易 SQL 编辑器

          先上干货!

          <template> <div ref="codeContainer" class="editor-container" :style="{ height: height + 'px' }" /> </template> <script> import * as monaco from 'monaco-editor' /** * VS Code 编辑器 * * 通过 getEditorVal 函数向外传递编辑器即时内容 * 通过 initValue 用于初始化编辑器内容。 * 编辑器默认 sql 语言,支持的语言请参考 node_modules\monaco-editor\esm\vs\basic-languages 目录下~ * 编辑器样式仅有 'vs', 'vs-dark', 'hc-black' 三种 */ export default { name: 'MonacoEditor', props: { initValue: { type: String, default: '', }, readOnly: Boolean, language: { type: String, default: 'sql', }, height: { type: Number, default: 300, }, theme: { type: String, default: 'vs', }, }, data() { return { monacoEditor: null, // 语言编辑器 } }, computed: { inputVal() { return this.monacoEditor?.getValue() }, }, watch: { inputVal() { if (this.monacoEditor) { this.$emit('change', this.monacoEditor.getValue()) } }, theme() { this.setTheme(this.theme) }, height() { this.layout() }, }, mounted() { this.initEditor() }, beforeDestroy() { if (this.monacoEditor) { this.monacoEditor.dispose() } }, methods: { initEditor() { if (this.$refs.codeContainer) { this.registerCompletion() // 初始化编辑器,确保dom已经渲染 this.monacoEditor = monaco.editor.create(this.$refs.codeContainer, { value: '', // 编辑器初始显示文字 language: 'sql', // 语言 readOnly: this.readOnly, // 是否只读 Defaults to false | true automaticLayout: true, // 自动布局 theme: this.theme, // 官方自带三种主题vs, hc-black, or vs-dark minimap: { // 关闭小地图 enabled: false, }, tabSize: 2, // tab缩进长度 }) } this.setInitValue() }, focus() { this.monacoEditor.focus() }, layout() { this.monacoEditor.layout() }, getValue() { return this.monacoEditor.getValue() }, // 将 initValue Property 同步到编辑器中 setInitValue() { this.monacoEditor.setValue(this.initValue) }, setTheme() { monaco.editor.setTheme(this.theme) }, getSelectionVal() { const selection = this.monacoEditor.getSelection() // 获取光标选中的值 const { startLineNumber, endLineNumber, startColumn, endColumn } = selection const model = this.monacoEditor.getModel() return model.getValueInRange({ startLineNumber, startColumn, endLineNumber, endColumn, }) }, setPosition(column, lineNumber) { this.monacoEditor.setPosition({ column, lineNumber }) }, getPosition() { return this.monacoEditor.getPosition() }, }, } </script> <style lang="scss" scoped></style>

          相关功能

          获取选中代码

          getSelectionVal() { const selection = this.monacoEditor.getSelection() // 获取光标选中的值 const { startLineNumber, endLineNumber, startColumn, endColumn } = selection const model = this.monacoEditor.getModel() return model.getValueInRange({ startLineNumber, startColumn, endLineNumber, endColumn, }) },

          如何构建Monaco Editor SQL代码提示编辑器实例的详细教程?

          替换选中代码

          insertStringInTemplate(str) { const selection = this.monacoEditor.getSelection() // 获取光标选中的值 const { startLineNumber, endLineNumber, startColumn, endColumn } = selection const model = this.monacoEditor.getModel() const textBeforeSelection = model.getValueInRange({ startLineNumber: 1, startColumn: 0, endLineNumber: startLineNumber, endColumn: startColumn, }) const textAfterSelection = model.getValueInRange({ startLineNumber: endLineNumber, startColumn: endColumn, endLineNumber: model.getLineCount(), endColumn: model.getLineMaxColumn(model.getLineCount()), }) this.monacoEditor.setValue(textBeforeSelection + str + textAfterSelection) this.monacoEditor.focus() this.monacoEditor.setPosition({ lineNumber: startLineNumber, column: startColumn + str.length, }) },

          处理光标位置

          setPosition(column, lineNumber) { this.monacoEditor.setPosition({ column, lineNumber }) }, getPosition() { return this.monacoEditor.getPosition() },

          自定义 SQL 库表提示,并保留原有 SQL 提示

          首先由后端提供具体的库表信息:

          export const hintData = { adbs: ['dim_realtime_recharge_paycfg_range', 'dim_realtime_recharge_range'], dimi: ['ads_adid', 'ads_spec_adid_category'], }

          然后根据已有库表信息进行自定义 AutoComplete

          import * as monaco from 'monaco-editor' import { language } from 'monaco-editor/esm/vs/basic-languages/sql/sql' const { keywords } = language export default { ... mounted() { this.initEditor() }, methods: { ... registerCompletion() { const _that = this monaco.languages.registerCompletionItemProvider('sql', { triggerCharacters: ['.', ...keywords], provideCompletionItems: (model, position) => { let suggestions = [] const { lineNumber, column } = position const textBeforePointer = model.getValueInRange({ startLineNumber: lineNumber, startColumn: 0, endLineNumber: lineNumber, endColumn: column, }) const tokens = textBeforePointer.trim().split(/\s+/) const lastToken = tokens[tokens.length - 1] // 获取最后一段非空字符串 if (lastToken.endsWith('.')) { const tokenNoDot = lastToken.slice(0, lastToken.length - 1) if (Object.keys(_that.hintData).includes(tokenNoDot)) { suggestions = [..._that.getTableSuggest(tokenNoDot)] } } else if (lastToken === '.') { suggestions = [] } else { suggestions = [..._that.getDBSuggest(), ..._that.getSQLSuggest()] } return { suggestions, } }, }) }, // 获取 SQL 语法提示 getSQLSuggest() { return keywords.map((key) => ({ label: key, kind: monaco.languages.CompletionItemKind.Enum, insertText: key, })) }, getDBSuggest() { return Object.keys(this.hintData).map((key) => ({ label: key, kind: monaco.languages.CompletionItemKind.Constant, insertText: key, })) }, getTableSuggest(dbName) { const tableNames = this.hintData[dbName] if (!tableNames) { return [] } return tableNames.map((name) => ({ label: name, kind: monaco.languages.CompletionItemKind.Constant, insertText: name, })) }, initEditor() { if (this.$refs.codeContainer) { this.registerCompletion() // 初始化编辑器,确保dom已经渲染 this.monacoEditor = monaco.editor.create(this.$refs.codeContainer, { value: '', // 编辑器初始显示文字 language: 'sql', // 语言 readOnly: this.readOnly, // 是否只读 Defaults to false | true automaticLayout: true, // 自动布局 theme: this.theme, // 官方自带三种主题vs, hc-black, or vs-dark minimap: { // 关闭小地图 enabled: false, }, tabSize: 2, // tab缩进长度 }) } this.setValue(this.value) }, } }

          编辑器 resize

          resize() { this.monacoEditor.layout() },

          编辑器设置主题

          注意!设置主题并非在编辑器实例上修改的哦!

          setTheme() { monaco.editor.setTheme(this.theme) },

          SQL 代码格式化

          编辑器自身不支持 sql 格式化(试了下 JavaScript 是支持的),所以用到了 sql-formatter 这个库。

          import { format } from 'sql-formatter' ... format() { this.monacoEditor.setValue( format(this.monacoEditor.getValue(), { indentStyle: 'tabularLeft', }), ) }, ...

          右键菜单汉化

          需要安装以下两个库

          npm install monaco-editor-nls --save npm install monaco-editor-esm-webpack-plugin --save-dev

          具体用法可以直接去 www.npmjs.com/package/mon… 里面看,我就不搬运了~

          记得销毁编辑器对象哦

          beforeDestroy() { if (this.monacoEditor) { this.monacoEditor.dispose() } },

          踩坑

          下面是我遇到的几个坑。

          • 最新版本的 Monaco Editor 已经使用了 ES2022 的语法,所以老项目可能会出现编译不过的问题。所以我把版本调低了一些。
          • 在最初调试编辑器的时候出现了无法编辑的情况,后来发现是同事用到了 default-passive-events 这个库来关闭 chrome 的 Added non-passive event listener to a scroll-blocking <some> event. Consider marking event handler as 'passive' to make the page more responsive 警告。结果拦截一些 event。

          如何快速去看懂 Monaco Editor

          一开始我看它的官方文档是非常懵的,各种接口、函数、对象的定义,完全不像是个前端库那么好理解。鼓捣了好久才慢慢找到门路。

          • 先看示例
            • 查看它的 playground,上面其实是有一些功能可以直接找到的。
            • 查看它在 github 上的 /samples 目录,里面也有不少示例。
            • 去掘金这类网站上找别人写的示例,能有不少启发。
          • 再看 API
            • 了解了自己所需要的功能相关的代码,再去看它文档的 API 就会发现容易理解多了。逐步发散理解更多关联功能。

          参考资料

          • 官方文档

          microsoft.github.io/monaco-edit…

          相关库

          Monaco Editor www.npmjs.com/package/mon…

          右键菜单汉化 www.npmjs.com/package/mon…

          webpack 插件 www.npmjs.com/package/mon…

          汉化 webpack 插件 www.npmjs.com/package/mon…

          SQL 代码格式化 www.npmjs.com/package/sql…

          博客

          www.jb51.net/article/258307.htm

          www.jb51.net/article/258269.htm

          以上就是Monaco Editor开发SQL编辑器实例详解的详细内容,更多关于Monaco Editor开发SQL编辑器的资料请关注易盾网络其它相关文章!