• monaco-editor 实现SQL编辑器


    原文链接:https://www.yuque.com/sxd_panda/antv/editor

    安装

    yarn add monaco-editor
    或
    npm install monaco-editor
    

    配置

    看网上的教程需要添加vite配置,但是我的项目没有对vite进行配置,打包出来的也是可以用的,具体看你们的场景

    vite.config.js配置

    安装 vite-plugin-monaco-editor
    
    import monacoEditorPlugin from 'vite-plugin-monaco-editor'
    
    plugins: [
      monacoEditorPlugin({
        languageWorkers: ['editorWorkerService', 'typescript', 'json', 'html']
      }),
    ]
    

    页面使用

    先把对应的几个 worker 引入下,不然控制台会有警告。这段代码可以单独放在一个组件里面引入到当前页面,因为它目前的作用就是解决控制台警告的,写在当前页面也是没问题的

    import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';
    import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker';
    import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker';
    import htmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker';
    
    
    self.MonacoEnvironment = {
      getWorker(workerId, label) {
        if (label === 'json') {
          return new jsonWorker();
        }
        if (label === 'typescript' || label === 'javascript') {
          return new tsWorker();
        }
        if (label === 'html') {
          return new htmlWorker();
        }
        return new editorWorker();
      }
    };
    

    导入monaco模块准备初始化编辑器

    import * as monaco from 'monaco-editor';
    
    const initEditor = () => {
      monacoEditor = monaco.editor.create(editRef.value, {
        theme: 'vs-dark', // 主题
        language: 'sql',
        value: '',
        renderLineHighlight: 'gutter',
        // folding: true, // 是否折叠
        // roundedSelection: false,
        // foldingHighlight: true, // 折叠等高线
        // foldingStrategy: 'indentation', // 折叠方式  auto | indentation
        // showFoldingControls: 'always', // 是否一直显示折叠 always | mouseover
        // disableLayerHinting: true, // 等宽优化
        // emptySelectionClipboard: false, // 空选择剪切板
        // selectionClipboard: false, // 选择剪切板
        automaticLayout: true, // 自动布局
        codeLens: true, // 代码镜头
        // scrollBeyondLastLine: false, // 滚动完最后一行后再滚动一屏幕
        colorDecorators: true // 颜色装饰器
        // accessibilitySupport: 'on', // 辅助功能支持  "auto" | "off" | "on"
        // lineNumbers: 'on', // 行号 取值: "on" | "off" | "relative" | "interval" | function
        // lineNumbersMinChars: 5, // 行号最小字符   number
        // enableSplitViewResizing: false,
        // readOnly: false //是否只读  取值 true | false
      });
    };
    
    // 执行初始化的方法
    onMounted(() => {
      // 初始化编辑器
      initEditor();
    });
    

    如何添加SQL关键字提示?

    SQL关键字其实插件内是有的,我们只需要把它拿过啦直接用就行了,如果你觉得不全,可以自己定义一个js文件,把你需要的关键字都加入到这个文件中,后续维护就只需要维护你这个js文件就行了

    插件关键字的目录:/node_modules/monaco-editor/esm/vs/basic-languages/sql/sql.js

    import { language } from 'monaco-editor/esm/vs/basic-languages/sql/sql.js';
    
    // 注册SQL关键字提示
    monaco.languages.registerCompletionItemProvider('sql',{
      provideCompletionItems:(model, position) => {
        let suggestions = [];
        // language.keywords 是获取内置的SQL关键字
          language.keywords.map(item => {
          suggestions.push({
            label: item,
            kind: monaco.languages.CompletionItemKind['Keyword'],
            insertText: item + ' ',
            detail: '内置关键字',
          });
        });
         return {
            suggestions
          };
      }
    })
    

    如何添加表字段提示?

    type类型文档

    // 这个是自定义的表字段数据
    const fieldsArr = [
      {
        type: 'Field', // 这个类型是为了区分是关键字还是字段,具体可以看下文档
        value: 'name'
      },
      {
        type: 'Field',
        value: 'age'
      },
      {
        type: 'Field',
        value: 'sex'
      }
    ];
    
    
    
    monaco.languages.registerCompletionItemProvider('sql',{
      provideCompletionItems:(model, position) => {
        let suggestions = [];
       // 再把内置的关键字数据处理下
        const temp = language.keywords.map(item => {
          return {
            type: 'Keyword',
            value: item
          };
        });
    // 把关键字和表字段数据合到一起,这样就不用输入快捷键才会显示表字段了
    const result = [...fieldsArr, ...temp];
    result.map(item => {
      suggestions.push({
        label: item.value,
        kind: monaco.languages.CompletionItemKind[item.type],
        insertText: item.value + ' ',
        detail: item.type == 'Keyword' ? '内置关键字' : '表字段',
        range
      });
    });
         return {
            suggestions
          };
      }
    })
    
    


    添加代码格式化右键菜单

    SQL编辑器默认是没有右键格式化代码的,需要手动添加菜单并借助第三方的插件实现SQL代码的格式化

    插件链接:https://www.npmjs.com/package/sql-formatter

    # 安装格式化插件
    npm install sql-formatter   /   yarn add sql-formatter
    
    import { format } from 'sql-formatter';
    
    // 创建自定义菜单项
    monacoEditor.addAction({
      id: 'format.sql',
      label: 'Formart SQL',
      precondition: null,
      contextMenuGroupId: 'navigation',
      contextMenuOrder: 1,
      run: function () {
        // sql代码格式化
        monacoEditor.setValue(format(monacoEditor.getValue()));
      }
    });
    

    自定义主题

    function defineTheme() {
      monaco.editor.defineTheme('naruto', {
        base: 'vs', // 以哪个默认主题为基础:"vs" | "vs-dark" | "hc-black" | "hc-light"
        inherit: true,
        rules: [
          // 高亮规则,即给代码里不同token类型的代码设置不同的显示样式
          { token: 'identifier', foreground: '#d06733' },
          { token: 'number', foreground: '#6bbeeb', fontStyle: 'italic' },
          { token: 'keyword', foreground: '#05a4d5' }
        ],
        colors: {
          'scrollbarSlider.background': '#edcaa6', // 滚动条背景
          'editor.foreground': '#0d0b09', // 基础字体颜色
          'editor.background': '#00090B', // 背景颜色
          'editorCursor.foreground': '#d4b886', // 焦点颜色
          'editor.lineHighlightBackground': '#6492a520', // 焦点所在的一行的背景颜色
          'editorLineNumber.foreground': '#008800' // 行号字体颜色
        }
      });
    }
    defineTheme();
    
    monaco.editor.setTheme('naruto');
    

    下面这个是已经实现的demo效果

  • 相关阅读:
    [附源码]计算机毕业设计JAVAjsp校外教育机构类网站
    记一次失败的pip使用经历
    第二篇:Sentinel之SPI机制使用与源码分析
    【理论学习】Vision-Transformer
    安装rabbitMQ
    java计算机毕业设计ssm齐市疫苗管理系统w80jw(附源码、数据库)
    【小沐学前端】Node.js实现基于Protobuf协议的UDP通信(UDP/TCP)
    python版opencv人脸训练与人脸识别
    StarRocks入门之路
    2022-07-01 Dubbo&&Zookeeper
  • 原文地址:https://www.cnblogs.com/sxdpanda/p/18237357