vue3 使用 monaco-editor 自定义代码补全。

这篇具有很好参考价值的文章主要介绍了vue3 使用 monaco-editor 自定义代码补全。。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

使用场景:

        数据编辑时需要支持sql语法高亮, 并且支持自定义代码提示补全。

monaco详细说明和使用可参考另一篇发文Monaco Editor (vite/webpack + ts + vue项目使用)

步骤一:安装依赖 

npm i monaco-editor

步骤二:组件功能封装

<template>
  <div ref="cusEditor"></div>
</template>
<script setup lang="ts">
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api'
import { withDefaults, defineProps, ref, defineEmits, onMounted, onUnmounted, watch } from 'vue'
import { OPTIONS_BASE } from './registerCompletion'
import './worker'
interface IProps {
  modelValue: string
  disabled?: boolean
  editorConfig?: { language: string; theme: 'vs' | 'vs-dark' | 'hc-black' }
}
const props = withDefaults(defineProps<IProps>(), {
  modelValue: '',
  disabled: false,
  editorConfig: () => ({ language: 'sql', theme: 'vs-dark' }),
})

const cusEditor = ref<HTMLElement | null>(null)
let editor: Partial<monaco.editor.IStandaloneCodeEditor> = {}
const emit = defineEmits(['update:modelValue'])
/**初始化编辑器 */
onMounted(() => {
  onDispose()
  if (cusEditor.value) {
    editor = monaco.editor.create(cusEditor.value, { ...OPTIONS_BASE, ...props.editorConfig, readOnly: props.disabled })
    editor.onDidChangeModelContent &&
      editor.onDidChangeModelContent(() => {
        const value = editor.getValue && editor.getValue() // 给父组件实时返回最新文本
        emit('update:modelValue', value)
      })
  }
})
/**销毁实例 */
const onDispose = () => {
  editor && editor.dispose && editor.dispose()
}
onUnmounted(() => {
  onDispose()
})
/**修改只读状态 */
watch(
  () => props.disabled,
  (val) => {
    editor.updateOptions && editor.updateOptions({ readOnly: val })
  }
)
/**修改配置 */
watch(
  () => props.editorConfig,
  (val) => {
    const model = editor.getModel && editor.getModel()
    if (model) {
      monaco.editor.setModelLanguage(model, val.language)
      monaco.editor.setTheme(val.theme)
    }
  },
  { deep: true }
)
/**回显数据 */
watch(
  () => props.modelValue,
  (val) => {
    if (editor) {
      const value = editor.getValue && editor.getValue()
      if (val !== value) {
        editor.setValue && editor.setValue(val || '')
      }
    }
  }
)
</script>
  • OPTIONS_BASE :  为基础配置,具体参数可参考官网
  • worker: 解决vite引入代码高亮和错误提示

参考git, discussions

OPTIONS_BASE:

export const OPTIONS_BASE: monaco.editor.IStandaloneEditorConstructionOptions = {
  value: '', // 初始显示文字
  lineNumbers: 'on', // 是否展示行号 'off' | 'on
  automaticLayout: false, // 自适应布局 默认true
  minimap: {
    enabled: false,
  },
  tabSize: 2,
  fontSize: 16
}

worker.ts

import * as monaco from 'monaco-editor';
import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'
import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker'
import cssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker'
import htmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker'
import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker'

self.MonacoEnvironment = {
  getWorker(_, label) {
    if (label === 'json') {
      return new jsonWorker()
    }
    if (label === 'css' || label === 'scss' || label === 'less') {
      return new cssWorker()
    }
    if (label === 'html' || label === 'handlebars' || label === 'razor') {
      return new htmlWorker()
    }
    if (label === 'typescript' || label === 'javascript') {
      return new tsWorker()
    }
    return new editorWorker()
  }
}
monaco.languages.typescript.typescriptDefaults.setEagerModelSync(true);

步骤三:组件的使用

<template>
    <el-form-item label="表名:" prop="table">
      <MonacoEditor class="w-full h-40" v-model="formData.table" :disabled="disabled" :constModelData="constModelData"></MonacoEditor>
    </el-form-item>
</template>
<script lang="ts" setup>
    import MonacoEditor from '@/components/monaco/index.vue'
</script>

到此,就可以实现基础的编辑功能

*扩展

由于我项目中使用的时sql语法,并且还需要支持自定义代码补全, 接下来就以sql语言为例:

步骤一:自定义补全语法方法封装

import * as monaco from 'monaco-editor';
/**
 * 注册:自定义语法补全
 * @param language 语言类型
 * @param constValues 常量提示
 */
export const registerProvider = (language: string, constValues: string[]) => {
  const monacoProvider = monaco.languages.registerCompletionItemProvider(language, {
    provideCompletionItems: function (model, position) {
      // 获取当前行数
      const line = position.lineNumber
      // 获取当前列数
      const column = position.column
      // 获取当前输入行的所有内容
      const content = model.getLineContent(line)
      // 通过下标来获取当前光标后一个内容,即为刚输入的内容
      const sym = content[column - 2]
      const word = model.getWordUntilPosition(position)
      const range = {
        startLineNumber: position.lineNumber,
        endLineNumber: position.lineNumber,
        startColumn: word.startColumn,
        endColumn: word.endColumn,
      }
      let suggestions: any[] = []
      if (sym === '$') {
        suggestions = constValues.map((e) => ({
          label: e,
          kind: monaco.languages.CompletionItemKind.Keyword,
          insertText: '{' + e + '}',
          detail: '常量配置',
        }))
        //拦截到用户输入$,开始设置提示内容,同else中代码一致,自行拓展
      } else if(language === 'sql'){
        // 直接提示,以下为sql语句关键词提示
        var sqlStr = ['SELECT', 'FROM', 'WHERE', 'AND', 'OR', 'LIMIT', 'ORDER BY', 'GROUP BY', 'LEFT', 'ON', 'if(){}', 'for(){}', 'size', 'get()', 'substring', 'return']
        suggestions = sqlStr.map((e) => ({
          label: e, // 显示的提示内容
          kind: monaco.languages.CompletionItemKind['Function'], // 用来显示提示内容后的不同的图标
          insertText: e, // 选择后粘贴到编辑器中的文字
          detail: '', // 提示内容后的说明
          range: range,
        }))
      }
      return {
        suggestions: suggestions,
      }
    },
    triggerCharacters: ['$', ''],
  })
  return monacoProvider
}

步骤二: 组件中使用

import { registerProvider } from '@/components/monaco/registerCompletion'
const registerPro = registerProvider('sql', props.constModelData)

效果展示:

1.sql关键字提示 

vue3 使用 monaco-editor 自定义代码补全。,vue.js,java

2.常量提示:

vue3 使用 monaco-editor 自定义代码补全。,vue.js,java

问题:每打开一次编辑弹框, 常量的提示就多一条重复数据。如图:

      vue3 使用 monaco-editor 自定义代码补全。,vue.js,java

        原因: registerCompletionItemProvider多次注册。由于自定义补全注册的代码写在了编辑弹框中,所以每打开一次弹框就执行一次注册自定义补全的方法,。

解决方案一:将注册方法移动到最外层组件中可解决

但是 由于功能需求,常量的提示内容要根据每次打开的弹框数据改变, 所以注册方法必须写在内部,(编辑弹框打开后,需根据弹框绑定数据的id去请求常量接口, 然后注册)

解决方案:参考官方:https://github.com/microsoft/monaco-editor/issues/2084

解决方案二:dispose(), 页面卸载时,销毁之前注册的实例文章来源地址https://www.toymoban.com/news/detail-741442.html

const registerPro = registerProvider('sql', props.constModelData)
onUnmounted(() => {
  registerPro && registerPro.dispose()
})

到了这里,关于vue3 使用 monaco-editor 自定义代码补全。的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • monaco,monaco-editor,monaco-editor-webpack-plugin,

    \\\"Monaco\\\"是包含了Monaco Editor和Monaco Language Server两个项目的总称,而\\\"Monaco Editor\\\"是Monaco项目中的一个部分,它是一款基于Web技术的高性能代码编辑器。 Monaco Language Server是一个支持多种语言的语言服务器,可以提供语法分析、代码补全、错误检查、重构等功能。Monaco Editor可以与

    2024年02月14日
    浏览(34)
  • @monaco-editor/react组件CDN加载失败解决办法

    @monaco-editor/react引入这个cdn资源会load失败 网上很多例子都是这样写的,我这样写monaco会报错 改成这样

    2024年02月15日
    浏览(25)
  • Vue集成Monaco Editor的使用,以及开发Python代码编辑器和Sql等

    ​微软之前有个项目叫做Monaco Workbench,后来这个项目变成了VSCode,而Monaco Editor(下文简称monaco)就是从这个项目中成长出来的一个web编辑器,他们很大一部分的代码(monaco-editor-core)都是共用的,所以monaco和VSCode在编辑代码,交互以及UI上几乎是一摸一样的,有点不同的是,

    2024年02月11日
    浏览(43)
  • react-app框架——使用monaco editor实现online编辑html代码编辑器

    大家好,我是yma16,本文分享关于 react-app框架——使用monaco editor实现online编辑html代码编辑器。 monaco editor 编辑器 Monaco Editor是一款功能强大的Web编辑器,由微软开发并使用在多个项目中。它是基于VS Code编辑器的核心组件,具有类似的功能和用户体验。 Monaco Editor具有以下特点

    2024年01月20日
    浏览(37)
  • 代码编辑器之monaco editor

    (一)简介 底层vscode开发的一款编辑器,各方面的样式功能基本与vscode一致。 (二)官方文档 Monaco Editor (microsoft.github.io) (三)安装 安装时两者版本要对应,对应表在后面 (四)属性 以下是较为常见的属性 (五) 方法 挑选出使用频次较高的 monaco.editor.setTheme(‘主题色名字

    2024年02月21日
    浏览(31)
  • vscode vue3自定义自动补全

    敲代码多了,发现重发动作很多,于是还是定义自动补全代码吧——懒是第一生产力! 1,Ctrl + Shift + P打开快捷命令行 :找到下面这个 2,然后找到ts:  里面给了demo照着写就行   然后重复上面的步骤 不选ts,选vue: ,后续继续添加

    2024年02月11日
    浏览(30)
  • Monaco Editor教程(二十):在编辑器的某个特定位置插入自定义的dom内容,图片,表单,表格,视频

    哇咔咔,这是我的第20篇Monaco教程,写完这一篇会暂时休息一段时间,练练字,存存稿,读读书,顺便修修文章。 目前全网成系统的monaco中文专栏应该只有我这一个,欢迎评论区打脸。自结束了GitLab CI/CD的专栏后,我就一直在利用业余时间学习Monaco相关的知识,一是为了弥补

    2023年04月16日
    浏览(41)
  • vue3代码编辑器组件codemirror-editor-vue3

    官方文档:https://github.com/RennCheung/codemirror-editor-vue3 国内镜像:https://renncheung.github.io/codemirror-editor-vue3/zh-CN/guide/getting-started 参考文档:https://codemirror.net/5/mode/index.html 点击参考文档,选择语言并点击在文章最后找到mode的格式 在配置项中修改mode,并引入对应语言js 如使用pyt

    2024年02月14日
    浏览(27)
  • 使用 monaco-editor-nls 汉化 右键菜单汉化部分失败原因

    首先使用npm或者其他包管理工具安装依赖插件: 如果右键菜单汉化一部分失败,首先去项目下看node_modules/monaco-editor-nls/locale/zh-hans中搜vs/editor/contrib/format/看一下是否有路径有brower字段,再去对应的node_modules/monaco-editor/esm/vs/editor/contrib/format/formatActions看是否有brower文件夹 如果

    2024年02月15日
    浏览(31)
  • vue3 wangeditor/editor富文本使用和编辑

    第一步:安装 第二步:使用 最终效果图: 第四:工具栏配置 进入官方demo:https://www.wangeditor.com/demo/index.html 打开之后,按F12在控制台输入 toolbar.getConfig()  查看工具栏的默认配置。  如果有不需要的工具栏项,可以在  toolbarConfig.excludeKeys 中配置

    2024年01月21日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包