欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

vue codemirror实现在线代码编译器

程序员文章站 2022-03-02 08:58:35
前言如果我们想在web端实现在线代码编译的效果,那么需要使用组件vue-codemirror,他是将codemirror进行了再次封装 支持代码高亮 62种主题颜色,例如monokai等等...

前言

如果我们想在web端实现在线代码编译的效果,那么需要使用组件vue-codemirror,他是将codemirror进行了再次封装

  • 支持代码高亮
  • 62种主题颜色,例如monokai等等
  • 支持json, sql, javascript,css,xml, html,yaml, markdown, python编辑模式,默认为 json
  • 支持快速搜索
  • 支持自动补全提示
  • 支持自动匹配括号

环境准备

npm install jshint
npm install jsonlint
npm install script-loader
npm install vue-codemirror

封装组件

我们可以在项目中的components中将vue-codemirror进行再次封装

<template>
  <codemirror
    ref="mycm"
    v-model="editorvalue"
    :options="cmoptions"
    @changes="oncmcodechanges"
    @blur="oncmblur"
    @keydown.native="onkeydown"
    @mousedown.native="onmousedown"
    @paste.native="onpaste"
  >
  </codemirror>
</template>

<script>
import { codemirror } from "vue-codemirror";
import 'codemirror/keymap/sublime'
import "codemirror/mode/javascript/javascript.js";
import "codemirror/mode/xml/xml.js";
import "codemirror/mode/htmlmixed/htmlmixed.js";
import "codemirror/mode/css/css.js";
import "codemirror/mode/yaml/yaml.js";
import "codemirror/mode/sql/sql.js";
import "codemirror/mode/python/python.js";
import "codemirror/mode/markdown/markdown.js";
import "codemirror/addon/hint/show-hint.css";
import "codemirror/addon/hint/show-hint.js";
import "codemirror/addon/hint/javascript-hint.js";
import "codemirror/addon/hint/xml-hint.js";
import "codemirror/addon/hint/css-hint.js";
import "codemirror/addon/hint/html-hint.js";
import "codemirror/addon/hint/sql-hint.js";
import "codemirror/addon/hint/anyword-hint.js";
import "codemirror/addon/lint/lint.css";
import "codemirror/addon/lint/lint.js";
import "codemirror/addon/lint/json-lint";
import 'codemirror/addon/selection/active-line'
import "codemirror/addon/hint/show-hint.js";
import "codemirror/addon/hint/anyword-hint.js";
require("script-loader!jsonlint");
import "codemirror/addon/lint/javascript-lint.js";
import "codemirror/addon/fold/foldcode.js";
import "codemirror/addon/fold/foldgutter.js";
import "codemirror/addon/fold/foldgutter.css";
import "codemirror/addon/fold/brace-fold.js";
import "codemirror/addon/fold/xml-fold.js";
import "codemirror/addon/fold/comment-fold.js";
import "codemirror/addon/fold/markdown-fold.js";
import "codemirror/addon/fold/indent-fold.js";
import "codemirror/addon/edit/closebrackets.js";
import "codemirror/addon/edit/closetag.js";
import "codemirror/addon/edit/matchtags.js";
import "codemirror/addon/edit/matchbrackets.js";
import "codemirror/addon/selection/active-line.js";
import "codemirror/addon/search/jump-to-line.js";
import "codemirror/addon/dialog/dialog.js";
import "codemirror/addon/dialog/dialog.css";
import "codemirror/addon/search/searchcursor.js";
import "codemirror/addon/search/search.js";
import "codemirror/addon/display/autorefresh.js";
import "codemirror/addon/selection/mark-selection.js";
import "codemirror/addon/search/match-highlighter.js";
export default {
  name: "index",
  components: {codemirror},
  props: ["cmtheme", "cmmode", "cmindentunit", "autoformatjson"],
  data() {
    return {
      editorvalue: '{}',
      cmoptions: {
        theme: !this.cmtheme || this.cmtheme === "default" ? "default" : this.cmtheme,  // 主题
        mode: !this.cmmode || this.cmmode === "default" ? "application/json" : this.cmmode,  // 代码格式
        tabsize: 4,  // tab的空格个数
        indentunit: !this.cmindentunit ? 2 : this.cmindentunit,  // 一个块(编辑语言中的含义)应缩进多少个空格
        autocorrect: true,  // 自动更正
        spellcheck: true,  // 拼写检查
        lint: true,  // 检查格式
        linenumbers: true,  //是否显示行数
        linewrapping: true, //是否自动换行
        styleactiveline: true,  //line选择是是否高亮
        keymap: 'sublime',  // sublime编辑器效果
        matchbrackets: true,  //括号匹配
        autoclosebrackets: true,  // 在键入时将自动关闭括号和引号
        matchtags: { bothtags: true },  // 将突出显示光标周围的标签
        foldgutter: true,  // 可将对象折叠,与下面的gutters一起使用
        gutters: [
          "codemirror-lint-markers",
          "codemirror-linenumbers",
          "codemirror-foldgutter"
        ],
        highlightselectionmatches: {
          minchars: 2,
          style: "matchhighlight",
          showtoken: true
        },
      },
      enableautoformatjson: this.autoformatjson == null ? true : this.autoformatjson,  // json编辑模式下,输入框失去焦点时是否自动格式化,true 开启, false 关闭
    }
  },
  created() {
    try {
      if (!this.editorvalue) {
        this.cmoptions.lint = false;
        return;
      }
      if (this.cmoptions.mode === "application/json") {
        if (!this.enableautoformatjson) {
          return;
        }
        this.editorvalue = this.formatstrinjson(this.editorvalue);
      }
    } catch (e) {
      console.log("初始化codemirror出错:" + e);
    }
  },
  methods: {
    resetlint() {
      if (!this.$refs.mycm.codemirror.getvalue()) {
        this.$nexttick(() => {
          this.$refs.mycm.codemirror.setoption("lint", false);
        });
        return;
      }
      this.$refs.mycm.codemirror.setoption("lint", false);
      this.$nexttick(() => {
        this.$refs.mycm.codemirror.setoption("lint", true);
      });
    },
    // 格式化字符串为json格式字符串
    formatstrinjson(strvalue) {
      return json.stringify(
        json.parse(strvalue),
        null,
        this.cmindentunit
      );
    },
    oncmcodechanges(cm, changes) {
      this.editorvalue = cm.getvalue();
      this.resetlint();
    },
    // 失去焦点时处理函数
    oncmblur(cm, event) {
      try {
        let editorvalue = cm.getvalue();
        if (this.cmoptions.mode === "application/json" && editorvalue) {
          if (!this.enableautoformatjson) {
            return;
          }
          this.editorvalue = this.formatstrinjson(editorvalue);
        }
      } catch (e) {
        // 啥也不做
      }
    },
    // 按下键盘事件处理函数
    onkeydown(event) {
      const keycode = event.keycode || event.which || event.charcode;
      const keycombination =
          event.ctrlkey || event.altkey || event.metakey;
      if (!keycombination && keycode > 64 && keycode < 123) {
        this.$refs.mycm.codemirror.showhint({ completesingle: false });
      }
    },
    // 按下鼠标时事件处理函数
    onmousedown(event) {
      this.$refs.mycm.codemirror.closehint();
    },
    // 黏贴事件处理函数
    onpaste(event) {
      if (this.cmoptions.mode === "application/json") {
        try {
          this.editorvalue = this.formatstrinjson(this.editorvalue);
        } catch (e) {
          // 啥都不做
        }
      }
    },
  }
}
</script>

<style scoped>

</style>

此组件默认配置了json编译器,cmoptions中是代码编译器的配置项,需要额外的功能也可以去看官方文档配置
接下来看展示效果

vue codemirror实现在线代码编译器

可以看到我们输入了json格式的字符串,即使格式不正确,会给我们错误提示,并且也会给我们自动格式化

python编译器

我们封装的组件默认是json编译器,如果我们想使用其他语言,也很简单,只需要导入其他语言的mode

<template>
  <div>
    <el-button type="primary" icon="el-icon-circle-check-outline" @click="handleconfirm" round>
      点击保存
    </el-button>
    <el-button icon="el-icon-caret-right" type="info" @click="handleruncode" round>
      在线运行
    </el-button>
  <code-editor
    :cmtheme="cmtheme"
    :cmmode="cmmode"
  >
  </code-editor>
  </div>
</template>

<script>
import codeeditor from '@/components/codeeditor/index'
import 'codemirror/theme/monokai.css'  // 导入monokai主题
import 'codemirror/mode/python/python.js'  // 导入python
export default {
  name: "index",
  components: {
    codeeditor
  },
  data() {
    return {
      cmtheme: "monokai",
      cmmode: "python",
    }
  },
  methods: {
    handleconfirm() {},
    handleruncode() {}
  }
}
</script>

<style>
.codemirror {
  position: relative;
  height: 100vh;
  overflow: hidden;
  margin-top: 10px;
}
</style>
<style lang="scss" scoped>
</style>

效果如下

vue codemirror实现在线代码编译器

到此这篇关于vue codemirror实现在线代码编译器 的文章就介绍到这了,更多相关vue codemirror在线代码编译器 内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!