一: 功能介绍
1、 支持不同的代码编辑模式
目前仅支持支持json, sql, javascript,css,xml, html,yaml, markdown, python编辑模式,默认为 json
2、 支持使用不同主题
支持62种主题,默认为 blackboard
3、 支持 API 编程
目前支持修改样式,获取内容,修改编辑框内容值
4、 支持复制,黏贴,剪切,撤销等常见操作
5、 支持文件拖拽导入
支持鼠标拖拽文件到编辑框,编辑框自动展示被拖拽文件的内容(当然,不是所有文件都可以,比如word文件,.exe文件就不行)
6、 支持 json 格式化
1)json编辑模式下,鼠标失去焦点时自动格式化json字符串,支持定义开关该特性
2)支持自定义格式化化缩进,支持字符或数字,最大不超过10,默认缩进2个空格
3)json编辑模式下,黏贴json字符串到编辑框时,支持自动格式化编辑框内容
4)json编辑模式下,支持按Ctrl+Alt+L快捷键主动格式化当前json格式字符内容
7、 支持显示代码行号
8、 支持编辑时"智能"缩进
9、 支持代码折叠 / 展开
支持json, sql, javascript,css,xml, html,yaml, markdown, python等
10、 支持静态代码语法检查
目前仅支持支持 json,javascript
11、 支持批量替换
操作方法:
按Ctrl + Shift + r键,弹出框中输入要被替换的内容,回车,然后再次输入用于替换的内容,回车即可。
12、 支持快速搜索
操作方法:
按Ctrl + F,弹出框中输入要查找内容,回车
13、 支持跳转到指定行
操作方法:
按Alt + G 快捷键, 弹出快对话框中输入行号,回车即可
14、 支持鼠标点击高亮匹配单词
使用场景举例:鼠标点击某个单词,高亮其它区域和被点击单词相同的单词
15、 支持自动补全提示
目前仅支持 sql,javascript,html,python
备注:出现自动补全提示时,按tab键可自动补全
16、 支持自动补全括号,单、双引号
支持自动补全括号:(),[],{},单引号,双引号:'' ""
使用场景举例:输入 [ 时,自动显示为[],并且把光标定位在括号中间
17、 支持自动补全 xml 标签
支持输入完开放xml、html元素标签时,自动补齐右侧闭合标签、或者输入完 </ 时,自动补齐闭合标签
使用场景举例:输入完时自动补齐右侧
18、 支持自动匹配 xml 标签
xml、html编辑模式下,支持自动匹配标签
使用场景举例:鼠标点击时xml标签时(开放标签或闭合标签),自动高亮另一半标签
19、 支持自动匹配括号
使用场景举例:光标点击紧挨{、]括号左、右侧时,自动突出显示匹配的括号 }、]
20、 支持光标所在当前行背景高亮
21、 支持高亮选中内容
使用场景举例:按下鼠标左键,拖拽选择内容时,高亮被选中内容,文字反白
二:安装依赖
npm install jshint
npm install jsonlint
npm install script-loader
npm install vue-codemirror
三:在项目的components中将vue-codemirror进行再次封装,
在components创建(components/writsql/writsql.vue)
<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>
来看最终效果图