Vue 基于vue-codemirror实现的代码编辑器

功能介绍

1、 支持不同的代码编辑模式
目前仅支持支持json, sql, javascript,css,xml, html,yaml, markdown, python编辑模式,默认为 json

2、 支持使用不同主题
支持62种主题,默认为 blackboard

3、 支持文件拖拽导入
支持鼠标拖拽文件到编辑框,编辑框自动展示被拖拽文件的内容(当然,不是所有文件都可以,比如word文件,.exe文件就不行)

4、 支持json格式化
1)json编辑模式下,鼠标失去焦点时自动格式化json字符串,支持定义开关该特性
2)支持自定义格式化化缩进,支持字符或数字,最大不超过10,默认缩进2个空格
3)json编辑模式下,黏贴json字符串到编辑框时,支持自动格式化编辑框内容
4)json编辑模式下,支持按Ctrl+Alt+L快捷键主动格式化当前json格式字符内容
5、 支持显示代码行号

6、 支持编辑时“智能”缩进

7、 支持代码折叠/展开
支持json, sql, javascript,css,xml, html,yaml, markdown, python等

8、 支持静态代码语法检查
目前仅支持支持 json,javascript

9、 支持批量替换
操作方法:
按Ctrl + Shift + r键,弹出框中输入要被替换的内容,回车,然后再次输入用于替换的内容,回车即可。

10、 支持快速搜索
操作方法:
按Ctrl + F,弹出框中输入要查找内容,回车

11 、 支持跳转到指定行
操作方法:
按Alt + G 快捷键, 弹出快对话框中输入行号,回车即可

12、 支持鼠标点击高亮匹配单词
使用场景举例:鼠标点击某个单词,高亮其它区域和被点击单词相同的单词

13、 支持自动补全提示
目前仅支持 sql,javascript,html,python
备注:出现自动补全提示时,按tab键可自动补

14、 支持自动补全xml标签
支持输入完开放xml、html元素标签时,自动补齐右侧闭合标签、或者输入完 使用场景举例:输入完时自动补齐右侧

15、 支持自动匹配xml标签
xml、html编辑模式下,支持自动匹配标签
使用场景举例:鼠标点击时xml标签时(开放标签或闭合标签),自动高亮另一半标签

16、 支持自动匹配括号
使用场景举例:光标点击紧挨{、]括号左、右侧时,自动突出显示匹配的括号 }、]

17、 支持光标所在当前行背景高亮

18、 支持高亮选中内容
使用场景举例:按下鼠标左键,拖拽选择内容时,高亮被选中内容,文字反白

主要依赖安装

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

src/main.js配置

添加以下带背景色的部分的配置
import Vue from “vue”
import ElementUI from “element-ui”
import “element-ui/lib/theme-chalk/index.css”
// 引入jshint用于实现js自动补全提示
import jshint from “jshint”;
window.JSHINT = jshint.JSHINT;
// 引入代码编辑器
import { codemirror } from “vue-codemirror”;
import “codemirror/lib/codemirror.css”;
Vue.use(ElementUI);
Vue.use(codemirror);

编辑器组件实现

<template><codemirrorref="myCm":value="value":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/theme/blackboard.css";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"; 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 {components: {codemirror},props: ["cmTheme", "cmMode", "autoFormatJson", "jsonIndentation","value"],data() {return {editorValue: "",cmOptions: {theme:!this.cmTheme || this.cmTheme == "default"? "blackboard": this.cmTheme, mode:!this.cmMode || this.cmMode == "default"? "application/json": this.cmMode, extraKeys: {Tab: "autocomplete", "Ctrl-Alt-L": () => {try {if (this.cmOptions.mode == "application/json" &&this.value) {this.editorValue = this.formatStrInJson(this.value);}} catch (e) {this.$message.error("格式化代码出错:" + e.toString());}}                    },lineWrapping: true,//代码折叠lineNumbers: true,//是否显示行号autofocus: true,smartIndent: 4,// 自动缩进indentUnit: 4, //缩进单位tabSize: 4, //tab字符的宽度autocorrect: true,//自动更正spellcheck: true,//拼写检查lint: true,gutters: ["CodeMirror-lint-markers",//代码错误检测"CodeMirror-linenumbers","CodeMirror-foldgutter",//展开收起],foldGutter: true,matchTags: { bothTags: true },matchBrackets: true,styleActiveLine: true,autoRefresh: true,highlightSelectionMatches: {//显示当前所选单词minChars: 2,style: "matchhighlight", showToken: true },styleSelectedText: true,enableAutoFormatJson:this.autoFormatJson == null ? true : this.autoFormatJson,defaultJsonIndentation:!this.jsonIndentation ||typeof this.jsonIndentation != typeof 1? 2: this.jsonIndentation },enableAutoFormatJson:this.autoFormatJson == null ? true : this.autoFormatJson, defaultJsonIndentation: !this.jsonIndentation || typeof this.jsonIndentation != typeof 1? 2: this.jsonIndentation };},watch: {cmTheme: function(newValue, oldValue) {try {let theme = this.cmTheme == "default" ? "blackboard" : this.cmTheme;require("codemirror/theme/" + theme + ".css");this.cmOptions.theme = theme;this.resetLint();} catch (e) {this.$message.error("切换编辑器主题出错:" + e.toString());}},cmMode: function(newValue, oldValue) {this.$set(this.cmOptions, "mode", this.cmMode);this.resetLint();this.resetFoldGutter();}},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);})},resetFoldGutter() {this.$refs.myCm.codemirror.setOption("foldGutter", false);this.$nextTick(() => {this.$refs.myCm.codemirror.setOption("foldGutter", true);});},// 黏贴事件处理函数OnPaste(event) {if (this.cmOptions.mode == "application/json") {try {this.editorValue = this.formatStrInJson(this.value);} catch (e) {// 啥都不做}}},// 失去焦点时处理函数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();},onCmCodeChanges(cm, changes) {this.editorValue = cm.getValue();this.resetLint();this.$emint('onChangeCode',cm.getValue())},// 格式化字符串为json格式字符串formatStrInJson(strValue) {return JSON.stringify( JSON.parse(strValue),null, this.defaultJsonIndentation)}},created() {try {if (!this.value) {this.cmOptions.lint = false;return;}if (this.cmOptions.mode == "application/json") {if (!this.enableAutoFormatJson) {return;}this.editorValue = this.formatStrInJson(this.value);}} catch (e) {console.log("初始化codemirror出错:" + e); }};
</script>
<style>
.CodeMirror-selected {background-color: blue !important;
}
.CodeMirror-selectedtext {color: white !important;
}
.cm-matchhighlight {background-color: #ae00ae;
}
</style>

引用编辑器组件

<template><div class="code-mirror-div"><div class="tool-bar"><span>请选择主题</span><el-select v-model="cmTheme" placeholder="请选择" size="small" style="width:150px"><el-option v-for="item in cmThemeOptions" :key="item" :label="item" :value="item"></el-option></el-select><span style="margin-left: 10px">请选择编辑模式</span><el-selectv-model="cmEditorMode"placeholder="请选择"size="small"style="width:150px"@change="onEditorModeChange"><el-optionv-for="item in cmEditorModeOptions":key="item":label="item":value="item"></el-option></el-select></div><code-mirror-editorref="cmEditor":cmTheme="cmTheme":cmMode="cmMode":autoFormatJson="autoFormatJson":jsonIndentation="jsonIndentation":value="codeValue@onChangeCode="changeCode"></code-mirror-editor></div>
</template>
<script>// 使用时需要根据CodeMirrorEditor.vue的实际存放路径,调整from后面的组件路径,以便正确引用import CodeMirrorEditor from "@/common/components/public/CodeMirrorEditor";export default {components: {CodeMirrorEditor},data() {return {cmTheme: "default", // codeMirror主题// codeMirror主题选项cmThemeOptions: ["default","3024-day","3024-night","abcdef","ambiance","ayu-dark","ayu-mirage","base16-dark","base16-light","bespin","blackboard","cobalt","colorforth","darcula","dracula","duotone-dark","duotone-light","eclipse","elegant","erlang-dark","gruvbox-dark","hopscotch","icecoder","idea","isotope","lesser-dark","liquibyte","lucario","material","material-darker","material-palenight","material-ocean","mbo","mdn-like","midnight","monokai","moxer","neat","neo","night","nord","oceanic-next","panda-syntax","paraiso-dark","paraiso-light","pastel-on-dark","railscasts","rubyblue","seti","shadowfox","solarized dark","solarized light","the-matrix","tomorrow-night-bright","tomorrow-night-eighties","ttcn","twilight","vibrant-ink","xq-dark","xq-light","yeti","yonce","zenburn"],cmEditorMode: "default", // 编辑模式// 编辑模式选项cmEditorModeOptions: ["default","json","sql","javascript","css","xml","html","yaml","markdown","python"],cmMode: "application/json", //codeMirror模式jsonIndentation: 2, // json编辑模式下,json格式化缩进 支持字符或数字,最大不超过10,默认缩进2个空格autoFormatJson: true // json编辑模式下,输入框失去焦点时是否自动格式化,true 开启, false 关闭,codeValue:'[{text:"text1",value:"value1"}]',//代码};},methods: {// 切换编辑模式事件处理函数onEditorModeChange(value) {switch (value) {case "json":this.cmMode = "application/json";break;case "sql":this.cmMode = "sql";break;case "javascript":this.cmMode = "javascript";break;case "xml":this.cmMode = "xml";break;case "css":this.cmMode = "css";break;case "html":this.cmMode = "htmlmixed";break;case "yaml":this.cmMode = "yaml";break;case "markdown":this.cmMode = "markdown";break;case "python":this.cmMode = "python";break;default:this.cmMode = "application/json";}},//代码修改changeCode(value){this.codeValue = value;}}};</script>
<style>
.CodeMirror {position: absolute;top: 80px;left: 2px;right: 5px;bottom: 0px;padding: 2px;height: auto; overflow-y: auto;
}
.code-mirror-div {position: absolute;top: 0px;left: 2px;right: 5px;bottom: 0px;padding: 2px;
}
.tool-bar {top: 20px;margin: 30px 2px 0px 20px;}
</style>


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部