当前位置:   article > 正文

vite+vue3实现网页版编辑器,带高亮以及代码提示(SQL语言为例)_vue3 sql编辑器

vue3 sql编辑器

1、前言

实现网页版编辑器有比较成熟的插件,这里使用的是微软的开源组件monaco-editor,由于官网文
档较为晦涩难懂,结合中文文档,完成网页编辑器的代码高亮、代码
提示以及中文汉化等功能,以上功能以SQL语言为例,其余的都差不多

效果如下
在这里插入图片描述

2、安装monaco-editor

安装monaco-editor组件,安装0.44.0版本

image.png

为什么要安装这个版本呢?目前最新的是0.45版本,如果需要汉化的话安装0.44版本,下面在汉化地方会分析

安装命令
npm install monaco-editor@0.44.0 --save

3、使用配置

页面引用

<template>
  <div class="codemirror">
    <div id="monacoEditor" ref="monacoEditor" class="monaco-editor" />
  </div>
</template>
  • 1
  • 2
  • 3
  • 4
  • 5
<script setup>
import * as monaco from 'monaco-editor'
import { language } from 'monaco-editor/esm/vs/basic-languages/sql/sql'
import { onMounted, onBeforeUnmount, ref } from 'vue'
import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'
self.MonacoEnvironment = {
  getWorker(workerId, label) {
    return new editorWorker()
  }
}
// 定义从父组件接收的属性
const props = defineProps({
  option: Object
})
const code = ref('') // 代码

// 获取 SQL 的关键字
const { keywords } = language

let editor

// 初始化 SQL 代码和表格数据
const tables = {}

// 编辑器的主题设置
const theme = 'vs-dark'

// 组件挂载后创建编辑器实例
onMounted(() => {
  initAutoCompletion()
  editor = monaco.editor.create(document.getElementById('monacoEditor'), {
    value: 'select * from test limit 0,10',
    language: 'sql',
    readOnly: false,
    automaticLayout: true,
    colorDecorators: true, // 颜色装饰器
    theme: theme,
    minimap: {
      enabled: false
    },
    tabSize: 2,
    fontSize: 16
  })
})
// 组件卸载前销毁编辑器实例
onBeforeUnmount(() => {
  if (editor) {
    editor.dispose()
  }
})
/**
 * @description: 获取编辑器中填写的值
 */
function getValue() {
  return editor.getValue()
}
/**
 * @description: 初始化自动补全
 */
function initAutoCompletion() {
  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 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(tables).includes(tableName)) {
          suggestions = [...getFieldsSuggest(tableName)]
        }
      } else if (lastWord === '.') {
        suggestions = []
      } else {
        suggestions = [...getTableSuggest(), ...getKeywordsSuggest()]
      }

      return {
        suggestions
      }
    }
  })
}

/**
 * @description: 获取关键字的补全列表
 *
 */
function getKeywordsSuggest() {
  return keywords.map((key) => ({
    label: key,
    kind: monaco.languages.CompletionItemKind.Keyword,
    insertText: key
  }))
}

/**
 * @description: 获取表名的补全列表
 */
function getTableSuggest() {
  return Object.keys(tables).map((key) => ({
    label: key,
    kind: monaco.languages.CompletionItemKind.Variable,
    insertText: key
  }))
}

/**
 * @description: 根据表名获取字段补全列表
 * @param {*} tableName
 */
function getFieldsSuggest(tableName) {
  const fields = tables[tableName]
  if (!fields) {
    return []
  }
  return fields.map((name) => ({
    label: name,
    kind: monaco.languages.CompletionItemKind.Field,
    insertText: name
  }))
}
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131

在tables变量中可以加入需要提示的表名以及字段名

以上在vue3中实现后基本上实现了网页版的编辑器,sql语法高亮以及提示等相关功能,但是默认是英文的快捷提示以及功能列表都是英文的,在使用上有点麻烦

image.png

下面开始汉化

4、vite方式汉化组件

由于项目使用的是vite打包方式,没有使用webpack方式,网上教程大多是webpack方式汉化,webpack使用插件比较方便汉化,vite方式目前只找到一个插件vite-plugin-monaco-editor-nls,但是目前看GitHub上对应的monaco-editor版本是0.34.0,看issues上也有提到新的用不了

image.png

结合下方有人提到的修复方法,克隆了一份源码修改了上传npm了

npm install zjt_home_vite-plugin-monaco-editor-nls
  • 1

image.png
安装之后,配置一下vite.config.js

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
import MonacoEditorNlsPlugin, { esbuildPluginMonacoEditorNls, Languages } from 'zjt_home_vite-plugin-monaco-editor-nls'
import zh_CN from './public/main.i18n.json'
const mock = true
// https://vitejs.dev/config/
export default defineConfig({
  resolve: {
    alias: {
      '@': resolve('./src')
    }
  },
  build: {
    sourcemap: false
  },
  optimizeDeps: {
    /** vite 版本需要大于等于2.3.0 */
    esbuildOptions: {
      plugins: [
        esbuildPluginMonacoEditorNls({
          locale: Languages.zh_hans,
     
          localeData: zh_CN.contents
        })
      ]
    }
  },
  plugins: [
    vue(),
    MonacoEditorNlsPlugin({
      locale: Languages.zh_hans,
   
      localeData: zh_CN.contents
    })
  ]
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

由于插件自带的语言包太老了,所以得更新一下语言包。
可以直接在官方中文语言包中找到这个

image.png
放到自己项目里面或者cdn上都行,这种方式比较麻烦的就是官方更新了就得下载替换

完成以上步骤就可以实现这种汉化效果

image.png

image.png

下面说一下如果使用了最新版本0.45的话会出现什么,如果使用目前最新版本0.45的monaco-editor并使用汉化的话会报错,出现下方报错

image.png

解决方法就是在node_modules找到这个js文件把其中的localize2改成localize
image.png

image.png

这样就解决了可以正常使用了

目前来看vite打包方式使用Monaco-editor没有什么问题,问题大多出现在汉化上,没有webpack比较成熟的插件并有人维护的,如果想要开箱即用的话,可以使用webpack方式打包项目,就可以使用以下三个插件配合使用

  • monaco-editor-nls:是对整个编辑器的汉化处理,如果需要进行汉化,那么需要安装此包。
  • monaco-editor-locales-plugin: 也是用来汉化的插件。
  • monaco-editor-esm-webpack-plugin:针对汉化包所做的webpack插件,需要和汉化包配合使用。

vite方式就按照以上步骤就可以实现代码高亮,提示以及菜单汉化等功能。

补充一下GitHub地址:

https://github.com/pearone/vite-plugin-monaco-editor-nls

https://github.com/microsoft/vscode-loc/tree/main/i18n/vscode-language-pack-zh-hans

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/691160
推荐阅读
相关标签
  

闽ICP备14008679号