Vue(27)vue-codemirror实现在线代码编译器
前言
如果我们想在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中是代码编译器的配置项,需要额外的功能也可以去看官方文档配置
接下来看展示效果

可以看到我们输入了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(27)vue-codemirror实现在线代码编译器的更多相关文章
- 在Vue中使用CodeMirror 格式显示错误 行数错乱 & 代码隐藏
		项目需要在线展示和编辑Json文件,所以需要找一个代码编辑器,因为我们的项目直接使用的 vueAdmin-template 这个模板 json编辑器也是直接从 vue-element-admin 项目 ... 
- 在vue项目中使用codemirror插件实现代码编辑器功能(代码高亮显示及自动提示
		在vue项目中使用codemirror插件实现代码编辑器功能(代码高亮显示及自动提示) 1.使用npm安装依赖 npm install --save codemirror; 2.在页面中放入如下代码 ... 
- Vue源码解析-调试环境-代码目录和运行构建
		目录 前言 1 代码结构 1.1 octotree插件 1.2 vue工程项目目录 1.3 主要代码目录src compiler core platforms server sfc shared 2 ... 
- Vue 源码解读(8)—— 编译器 之 解析(上)
		特殊说明 由于文章篇幅限制,所以将 Vue 源码解读(8)-- 编译器 之 解析 拆成了上下两篇,所以在阅读本篇文章时请同时打开 Vue 源码解读(8)-- 编译器 之 解析(下)一起阅读. 前言 V ... 
- Vue 源码解读(8)—— 编译器 之 解析(下)
		特殊说明 由于文章篇幅限制,所以将 Vue 源码解读(8)-- 编译器 之 解析 拆成了两篇文章,本篇是对 Vue 源码解读(8)-- 编译器 之 解析(上) 的一个补充,所以在阅读时请同时打开 Vu ... 
- Vue 源码解读(9)—— 编译器 之 优化
		前言 上一篇文章 Vue 源码解读(8)-- 编译器 之 解析 详细详解了编译器的第一部分,如何将 html 模版字符串编译成 AST.今天带来编译器的第二部分,优化 AST,也是大家常说的静态标记. ... 
- Vue 源码解读(10)—— 编译器 之 生成渲染函数
		前言 这篇文章是 Vue 编译器的最后一部分,前两部分分别是:Vue 源码解读(8)-- 编译器 之 解析.Vue 源码解读(9)-- 编译器 之 优化. 从 HTML 模版字符串开始,解析所有标签以 ... 
- Js的在线代码编辑器:CodeMirror
		github地址:https://github.com/codemirror/CodeMirror/tree/master/demo 里面包含需要的js.css文件以及大量的示例 官网:https:/ ... 
- 前端vue实现pdf文件的在线预览
		3.前端vue实现pdf文件的在线预览 我是通过 <iframe> 标签就可以满足我工作的 pdf预览需求 如果<iframe> 无法满足需求 , 可以使用pdf.js这个插件 ... 
随机推荐
- 零基础学习java------37---------mybatis的高级映射(单表查询,多表(一对一,一对多)),逆向工程,Spring(IOC,DI,创建对象,AOP)
			一. mybatis的高级映射 1 单表,字段不一致 resultType输出映射: 要求查询的字段名(数据库中表格的字段)和对应的java类型的属性名一致,数据可以完成封装映射 如果字段和jav ... 
- oracle first_value,last_valus
			first_value和last_value 是用来去分析函数窗口中对应列的第一个值和最后一个值的函数. 语法如下: first_value(col [ignore NULLS]) over([PAR ... 
- Templates and Static variables in C++
			Function templates and static variables: Each instantiation of function template has its own copy of ... 
- 编译安装redis之快速增加redis节点
			#: 下载安装包 [root@localhost ~]# wget http://download.redis.io/releases/redis-4.0.14.tar.gz #:解压 [root@l ... 
- 【C/C++】最长公共子序列(LCS)/动态规划
			晴神这个的最巧妙之处,在于用dp[i][0] = dp[0][j] = 0的边界条件 这样从1的下标开始填数组的时候,递推公式dp[i-1][j-1]之类的不会报错 #include <iost ... 
- 【C/C++】例题3-5 生成元/算法竞赛入门经典/数组与字符串
			[题目] x+x的各位数之和为y,x为y的生成元. 求10万以内的n的最小生成元,无解输出0. [解答] 这是我根据自己的想法最初写的代码: #include<cstdio> #inclu ... 
- Docker从入门到精通(二)——安装Docker
			通过上面文章,我们大概知道了什么是Docker,但那都是文字功夫,具体想要理解,还得实操,于是这篇文章带着大家来手动安装Docker. 1.官方教程 https://docs.docker.com/e ... 
- Unity实现“笼中窥梦”的渲染效果
			效果 思路 5个面用5个RenderTexture来接受5个摄像机分别获取的小场景图像: RenderTexture就当成屏幕来理解,MainCamera是把画面显示在屏幕上,屏幕就是最大的Rende ... 
- Docker(4)-docker常用命令
			帮助命令 docker version # 查看docker的版本信息 docker info # 查看docker的系统信息,包含镜像和容器的数量 docker --help # 帮助命令 dock ... 
- apt和apt-get的区别
			目录 一.简介 二.apt vs apt-get 为什么apt首先被引入? apt和apt-get之间的区别 apt和apt-get命令之间的区别 我应该使用apt还是apt-get? 三.结论 一. ... 
