Vue2安装使用MonacoEditor方式(自定义语法,自定义高亮,自定义提示)

 更新时间:2023年04月17日 09:33:26   作者:前端程序猿i  
这篇文章主要介绍了Vue2安装使用MonacoEditor方式(自定义语法,自定义高亮,自定义提示),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

1.安装MonacoEditor

cnpm install -S editor@1.0.0
cnpm install -S monaco-editor@0.19.3
cnpm install -S monaco-editor-webpack-plugin@1.9.1

2.配置vue.config.js文件

const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
module.exports = {
  configureWebpack: {
    plugins: [
        new MonacoWebpackPlugin()
    ]
}

3.建立组件monaco.vue

<template>
  <div>
    <div class="code-container" ref="container"></div>
  </div>
</template>
 
<script>
import './icon/iconfont.css'
import * as monaco from 'monaco-editor'
import vCompletion from '@/utils/sql.js'//语法提示文件
export default {
  name: 'codeEditor',
  props: {
    opts: {
      type: Object,
      default() {
        return {
          language: 'java', // shell、sql、python
          readOnly: false, // 不能编辑
        }
      },
    },
    value:{
      type:String,
      default:''
    }
  },
  watch: {
    value: {
      handler(n) {
        if(this.showInit){//初次传值初始化一次
          this.init()
          this.showInit = false
        }
        this.monacoInstance.setValue(n)//剩余全部更新内容
      },
      deep: true,
    },
  },
  data() {
    return {
      monacoInstance: null,
      provider: null,
      hints: [],
      color: null,
      showInit:true
    }
  },
  created() {
    this.init()
  },
  mounted() {
    this.init()
  },
  beforeDestroy() {
    this.dispose()
  },
 
  methods: {
    cloneDeep(suggestions) {
      return JSON.parse(JSON.stringify(suggestions))
    },
    dispose() {
      if (this.monacoInstance) {
        if (this.monacoInstance.getModel()) {
          this.monacoInstance.getModel().dispose()
        }
        this.monacoInstance.dispose()
        this.monacoInstance = null
        if (this.provider) {
          this.provider.dispose()
          this.color.dispose()
          this.provider = null
        }
      }
    },
    init() {
      let that = this
      this.dispose()
      this.provider = monaco.languages.registerCompletionItemProvider('sql', {
        provideCompletionItems(model, position) {
          return {
            suggestions: that.cloneDeep(vCompletion),//自定义语法提示,代码补全
          }
        },
        triggerCharacters: ['.'],//输入点可触发代码提示
      })
        //自定义语法高亮
      this.color = monaco.languages.setMonarchTokensProvider('sql', {
        ignoreCase: true,
        tokenizer: {//需要什么颜色,就在里面用正则匹配
          root: [
            [
              /currentUser|#@|RsOk|#string|#switch|#case|selectSql|uuid|addOrderBy|addConditionRequired|countSql|addGroupBy|currentDateTime|addFieldExist|formData|simplePage|RsJson|[@]|RsJsonData|Local|select|#set|#include|#render|#end|#for|#if|#else|#elseif|from|where|addField|addConditionExist|table|SqlUtil|GROUP_CONCAT|BY|AND|ADD|Data|page|IF|as|SUM|MAX|min|AVG|COUNT|ROUND|LEFT|JOIN/,
              { token: 'keyword' },
            ], //蓝色
            [
              /[+]|[-]|[*]|[/]|[%]|[>]|[<]|[=]|[!]|[:]|[&&]|[||]/,
              { token: 'string' },
            ], //红色
            [/'.*?'|".*?"/, { token: 'string.escape' }], //橙色
            [/#--.*?\--#/, { token: 'comment' }], //绿色
            [/null/, { token: 'regexp' }], //粉色
            [/[{]|[}]/, { token: 'type' }], //青色
            // [/[\u4e00-\u9fa5]/, { token: 'predefined' }],//亮粉色
            // [/''/, { token: 'invalid' }],//红色
            // [/[\u4e00-\u9fa5]/, { token: 'number.binary' }],//浅绿
            [/(?!.*[a-zA-Z])[0-9]/, { token: 'number.hex' }], //浅绿
            [/[(]|[)]/, { token: 'number.octal' }], //浅绿
            // [/[\u4e00-\u9fa5]/, { token: 'number.float' }],//浅绿
          ],
        },
      })
      // 初始化编辑器实例
      this.monacoInstance = monaco.editor.create(this.$refs['container'], {
        value: this.value,
        theme: 'vs-dark',
        autoIndex: true,
        ...this.opts,
      })
      // 监听编辑器content变化事件
      this.monacoInstance.onDidChangeModelContent(() => {
        this.$emit('contentChange', this.monacoInstance.getValue())
      })
    },
  },
}
</script>
<style lang="scss" scope>
.code-container {
  width: 100%;
  height: 500px;
  overflow: hidden;
  border: 1px solid #eaeaea;
  .monaco-editor .scroll-decoration {
    box-shadow: none;
  }
}
</style>

4.建立语法提示文件sql.js

export default [
  /**   * 内置函数   */
  {
     label: 'if',//触发提示的文本
     kind: monaco.languages.CompletionItemKind.Function,
     insertText: `\n#if()\n\t\n #end`,//补全的文本
     insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
     detail: '流程控制'
   },  {
     label: 'if/else',
     kind: monaco.languages.CompletionItemKind.Function,
     insertText: '\n#if()\n\n #else\n\n #end',
     insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
     detail: '流程控制'
   }
 ]

5.父组件引入monaco.vue

<template>
  <div>
    <moaco v-model="value" :opts="opts" @contentChange="contentChange"></moaco>
  </div>
</template>
 
<script>
import monaco from '@/monaco.vue'
export default {
  components: {
    monaco,
  },
  data() {
    return {
      value: '',
      countent: '',
      opts: {
        value: '',
        readOnly: false, // 是否可编辑
        language: 'sql', // 语言类型
        theme: 'vs-dark', // 编辑器主题
      },
    }
  },
  methods: {
    contentChange(val) {
      //每次改变编辑器内容触发事件,先用一个值存放数据
      this.countent = val
    },
    submit() {
      //在你提交给后台时将this.countent赋值给value
      this.countent = this.value
    },
  },
}
</script>
 
<style>
</style>

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Vue.js axios响应拦截如何获取返回状态码

    Vue.js axios响应拦截如何获取返回状态码

    这篇文章主要介绍了Vue.js axios响应拦截如何获取返回状态码问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-01-01
  • Vue生产环境如何自动屏蔽console

    Vue生产环境如何自动屏蔽console

    这篇文章主要介绍了Vue生产环境如何自动屏蔽console问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-06-06
  • vuex中commit和dispatch的区别解析

    vuex中commit和dispatch的区别解析

    commit 和dispatch的区别在于commit是提交mutatious的同步操作,dispatch是分发actions的异步操作,本文重点给大家讲解vuex中commit和dispatch的区别,感兴趣的朋友一起看看吧
    2024-06-06
  • 如何隐藏element-ui中tree懒加载叶子节点checkbox(分页懒加载效果)

    如何隐藏element-ui中tree懒加载叶子节点checkbox(分页懒加载效果)

    这篇文章主要介绍了如何隐藏element-ui中tree懒加载叶子节点checkbox(分页懒加载效果),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07
  • 使用Vue+Django+Ant Design做一个留言评论模块的示例代码

    使用Vue+Django+Ant Design做一个留言评论模块的示例代码

    这篇文章主要介绍了使用Vue+Django+Ant Design做一个留言评论模块,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-06-06
  • Echart图表在项目中的前后端使用详解

    Echart图表在项目中的前后端使用详解

    图表在我们的项目中可以帮我们很明确的看到我们想要看到的数据,本文将主要介绍Echart图表在项目中前后端使用的详细教程,感兴趣的同学可以学习一下
    2021-11-11
  • vue中el-tree动态初始默认选中和全选实现方法

    vue中el-tree动态初始默认选中和全选实现方法

    这篇文章主要给大家介绍了关于vue中el-tree动态初始默认选中和全选实现的相关资料,eltree默认选中eltree是一种常用的树形控件,通常用于在网页上呈现树形结构的数据,例如文件夹、目录、组织结构等,需要的朋友可以参考下
    2023-09-09
  • 详解vue-router导航守卫

    详解vue-router导航守卫

    今天小编就为大家分享一篇关于详解vue-router导航守卫,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • 关于Vue 3.0引入百度地图不兼容的解决办法

    关于Vue 3.0引入百度地图不兼容的解决办法

    这篇文章主要介绍了关于Vue 3.0引入百度地图不兼容的解决办法,本文通过实例代码给大家分享解决方法,需要的朋友可以参考下
    2022-08-08
  • vue将单页面改造成多页面应用的方法

    vue将单页面改造成多页面应用的方法

    最近领导交我一个项目是使用 vue-cli 搭建的单页面应用。下面小编通过本文给大家介绍vue将单页面改造成多页面应用的方法 ,感兴趣的朋友一起看看吧
    2018-11-11

最新评论