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

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

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

开发环境

jshint 2.11.1

jsonlint 1.6.3

script-loader 0.7.2

vue 2.6.11

vue-codemirror 4.0.6

element-ui 2.13.1 (使用到element-ui message组件,提示错误消息,如果不想安装该组件,替换编辑器中的this.$message所在行函数代码即可)

 

功能介绍

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元素标签时,自动补齐右侧闭合标签、或者输入完 </ 时,自动补齐闭合标签

 

使用场景举例:输入完<book>时自动补齐右侧</book>

 

18、 支持自动匹配xml标签

xml、html编辑模式下,支持自动匹配标签

 

使用场景举例:鼠标点击时xml标签时(开放标签或闭合标签),自动高亮另一半标签

 

19、 支持自动匹配括号

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

 

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

 

21、 支持高亮选中内容

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

主要依赖安装

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";

 

import App from "./app/App"

 

...略

 

Vue.use(ElementUI);

Vue.use(codemirror);

 

...略

 

编辑器组件实现

<template>

   <codemirror

       ref="myCm"

       :value="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/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/html-lint.js";

// import "codemirror/addon/lint/css-lint.js";  

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"],

   data() {

       return {

           editorValue: "",

           cmOptions: {

               theme:

                   !this.cmTheme || this.cmTheme == "default"

                       ? "blackboard"

                       : this.cmTheme,

               mode:

                   !this.cmMode || this.cmMode == "default"

                       ? "application/json"

                       : this.cmMode,

               lineWrapping: true,

               lineNumbers: true,

               autofocus: true,

               smartIndent: false,

               autocorrect: true,

               spellcheck: true,

               extraKeys: {

                   Tab: "autocomplete",

                   "Ctrl-Alt-L": () => {

                       try {

                           if (

                               this.cmOptions.mode == "application/json" &&

                               this.editorValue

                           ) {

                               this.editorValue = this.formatStrInJson(

                                   this.editorValue

                               );

                           }

                       } catch (e) {

                           this.$message.error(

                               "格式化代码出错:" + e.toString()

                           );

                       }

                   }                    

               },

               lint: true,

               gutters: [

                   "CodeMirror-lint-markers",

                   "CodeMirror-linenumbers",

                   "CodeMirror-foldgutter"

               ],

               foldGutter: true,

               autoCloseBrackets: true,

               autoCloseTags: 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);

           });

       },

       // 修改编辑框样式

       setStyle(style) {

           try {

               this.$nextTick(() => {

                   let cm = this.$refs.myCm.$el.querySelector(".CodeMirror");

                   if (cm) {

                       cm.style.cssText = style;

                   } else {

                       this.$message.error(

                           "未找到编辑器元素,修改编辑器样式失败"

                       );

                   }

               });

           } catch (e) {

               this.$message.error("修改编辑器样式失败:" + e.toString());

           }

       },

       // 获取值

       getValue() {

           try {

               return this.$refs.myCm.codemirror.getValue();

           } catch (e) {

               let errorInfo = e.toString();

               this.$message.error("获取编辑框内容失败:" + errorInfo);

               return errorInfo;

           }

       },

       // 修改值

       setValue(value) {

           try {

               if (typeof value != typeof "") {

                   this.$message.error(

                       "修改编辑框内容失败:编辑宽内容只能为字符串"

                   );

                   return;

               }

               if (this.cmOptions.mode == "application/json") {

                   this.editorValue = this.formatStrInJson(value);

               } else {

                   this.editorValue = value;

               }

           } catch (e) {

               this.$message.error("修改编辑框内容失败:" + e.toString());

           }

       },

       // 黏贴事件处理函数

       OnPaste(event) {

           if (this.cmOptions.mode == "application/json") {

               try {

                   this.editorValue = this.formatStrInJson(this.editorValue);

               } 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();

       },

       // 格式化字符串为json格式字符串

       formatStrInJson(strValue) {

           return JSON.stringify(

               JSON.parse(strValue),

               null,

               this.defaultJsonIndentation

           );

       }

   },

   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);

           // this.$message.error("初始化codemirror出错:" + e);

       }

   }

};

</script>

 

<style>

.CodeMirror-selected {

   background-color: blue !important;

}

 

.CodeMirror-selectedtext {

   color: white !important;

}

 

.cm-matchhighlight {

   background-color: #ae00ae;

}

</style>

 

目录
相关文章
|
9月前
|
JavaScript
Vue 项目使用 json-editor (二)
Vue 项目使用 json-editor (二)
415 0
|
9月前
|
JavaScript
Vue在Element UI下使用富文本框插件quill-editor(我个人不推荐用这个复杂的富文本插件)
Vue在Element UI下使用富文本框插件quill-editor(我个人不推荐用这个复杂的富文本插件)
|
6月前
|
存储 JavaScript 前端开发
Vue中通过集成Quill富文本编辑器实现公告的发布。Vue项目中vue-quill-editor的安装与使用【实战开发应用】
文章展示了在Vue项目中通过集成Quill富文本编辑器实现公告功能的完整开发过程,包括前端的公告发布、修改、删除操作以及后端的数据存储和处理逻辑。
Vue中通过集成Quill富文本编辑器实现公告的发布。Vue项目中vue-quill-editor的安装与使用【实战开发应用】
|
6月前
|
JavaScript
在Vue项目中vue-quill-editor的安装与使用【详细图解+过程+包含图片的缩放拖拽】
文章详细介绍了在Vue项目中安装和使用`vue-quill-editor`的步骤,包括如何通过npm安装、局部挂载、在Vue页面中引入和配置使用。同时,还提供了如何实现图片的缩放和拖拽功能的进阶教程,涉及到安装额外的插件`quill-image-drop-module`和`quill-image-resize-module`,以及对Webpack配置的调整。最后,文章还提供了实际效果展示和一些后续可能的拓展功能,如上传视频和将图片上传到服务器等。
在Vue项目中vue-quill-editor的安装与使用【详细图解+过程+包含图片的缩放拖拽】
|
7月前
|
JavaScript
【vue】 vue2 中使用 Tinymce 富文本编辑器
【vue】 vue2 中使用 Tinymce 富文本编辑器
725 6
|
7月前
|
JSON JavaScript 数据格式
文本-----wangEditor的使用,设置和获取内容,展示HTML无样式怎么办????console同步展示怎样写,Vue的配置在Vue3配置文件中的配置,是editor中的v-model绑定的值
文本-----wangEditor的使用,设置和获取内容,展示HTML无样式怎么办????console同步展示怎样写,Vue的配置在Vue3配置文件中的配置,是editor中的v-model绑定的值
|
7月前
|
JavaScript
【vue】 Tinymce 富文本编辑器 不想让上传的图片转换成base64,而是链接
【vue】 Tinymce 富文本编辑器 不想让上传的图片转换成base64,而是链接
421 0
|
7月前
|
JavaScript 前端开发
vue 富文本编辑器 quill (含代码高亮、自定义字体、汉化、鼠标悬浮提示、组件封装等)
vue 富文本编辑器 quill (含代码高亮、自定义字体、汉化、鼠标悬浮提示、组件封装等)
413 0
|
7月前
|
SQL JavaScript
vue 代码编辑器 vue-codemirror
vue 代码编辑器 vue-codemirror
90 0
|
9月前
|
存储 JavaScript 前端开发
笔.COOL,一个功能完备、使用便捷的在线HTML/CSS/JS以及Vue编辑器和作品分享平台
笔.COOL是一个新兴的在线 HTML/CSS/JS 及 Vue 编辑器,提供实时预览和云端存储功能。用户可以随时随地编写和保存代码,同时分享作品给他人预览和学习。它也是一个实用的 BUG 复现工具,支持嵌入编辑器到博客,促进代码交流。社区活跃,适合开发者展示作品、获取灵感和学习。
111 1