最近工作中需要优化下之前的网页端代码编辑器。我作为后端开发,虽然做这个不专业,但也只能硬着头皮上啊,大量查阅资料,还是优化了一些内容的,在这里分享一下。如果有写的不对的地方,也请大家体谅下,毕竟纯手打很累的哈哈。

参考手册:

vue-codemirror github 地址: https://github.com/surmon-china/vue-codemirror
codemirror 中文文档:https://olindk.gitbooks.io/codemirror/content/configuration.html
codemirror 英文文档:https://codemirror.net/doc/manual.html#config

如何引入 vue-codemirror 就不详细写了,网上资料很多。在 vue-codemirror gitbub 中也有简单教程,此文章只列举一些我认为挺有用的功能。

options配置

codemirror 中最重要的就是配置,这里先贴出来我用的配置。

cmOptions: {theme: 'monokai',mode: '',readOnly: false,tabSize: 4, // 制表符indentUnit: 2, // 缩进位数lineNumbers: true,ineWiseCopyCut: true,viewportMargin: 1000,autofocus: true,autocorrect: true,spellcheck: true,specialChars: /[\u0000-\u001f\u007f-\u009f\u00ad\u061c\u200b-\u200f\u2028\u2029\ufeff\ufff9-\ufffc]/g,specialCharPlaceholder: function (ch) {let token = document.createElement("span");let content = "\u002e";token.className = "cm-invalidchar";if (typeof content == "string") {token.appendChild(document.createTextNode(content));}token.title = "\\u" + ch.charCodeAt(0).toString(16);token.setAttribute("aria-label", token.title);return token},extraKeys: {Tab: (cm) => {if (cm.somethingSelected()) {      // 存在文本选择cm.indentSelection('add');    // 正向缩进文本} else {                    // 无文本选择cm.replaceSelection(Array(cm.getOption("indentUnit") + 1).join(" "), "end", "+input");  // 光标处插入 indentUnit 个空格}},},lint: false,// 代码折叠gutters: ["CodeMirror-lint-markers","CodeMirror-linenumbers","CodeMirror-foldgutter"],lineWrapping: false,foldGutter: true, // 启用行槽中的代码折叠autoCloseBrackets: true, // 自动闭合符号autoCloseTags: true,matchTags: { bothTags: true },matchBrackets: true, // 在光标点击紧挨{、]括号左、右侧时,自动突出显示匹配的括号 }、]styleSelectedText: true,styleActiveLine: true,autoRefresh: true,highlightSelectionMatches: {minChars: 2,trim: true,style: "matchhighlight",showToken: false},hintOptions: {completeSingle: false}
}

1)代码自动提示和补全

代码提示和补全功能,需要引入 codemirror/addon/hint 目录中的如下文件

import 'codemirror/addon/hint/show-hint.css'
import 'codemirror/addon/hint/show-hint.js'
import 'codemirror/addon/hint/javascript-hint'
import 'codemirror/addon/hint/xml-hint'
import 'codemirror/addon/hint/sql-hint'
import 'codemirror/addon/hint/anyword-hint'

代码提示需要一个事件,我这里用的是 inputRead 事件(也可以用别的事件,效果会略微不同),当监听到输入时,判断是否需要提示,所以要在编辑器初始化完成时,启动这个监听,这里只监听了英文字母的输入。编辑器初始化好后会触发 @ready 事件,在 onCmReady 方法中监听 inputRead 事件。然后只要有英文字母输入,就会监听到,自动调用 cm 的 showHint 方法进行提示。

<codemirrorref="myCm"v-model="content":options="cmOptions"@ready="onCmReady"@blur="onCmBlur"@mousedown.native="onMouseDown">
</codemirror>onCmReady(cm) {// 这里的 cm 对象就是 codemirror 对象,等于 this.$refs.myCm.codemirror cm.on("inputRead", (cm, obj) => {if (obj.text && obj.text.length > 0) {let c = obj.text[0].charAt(obj.text[0].length - 1)if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {cm.showHint({ completeSingle:false })}}})
}

提示框的层级问题

基本上增加了如上内容后,在编写代码时就有提示功能了,但是我遇到个问题就是提示框不出来,但是在源码中加日志后发现提示文本是有打印且正确的,后来发现是层级问题。

找到提示框的样式如下,默认的 z-index 是10,太小了,我改到超过2000后才能显示出来。

.CodeMirror-hints {position: absolute;z-index: 10;overflow: hidden;list-style: none;margin: 0;padding: 2px;-webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2);-moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2);box-shadow: 2px 3px 5px rgba(0,0,0,.2);border-radius: 3px;border: 1px solid silver;background: white;font-size: 90%;font-family: monospace;max-height: 20em;overflow-y: auto;
}

最终的效果:

 2)代码折叠

代码折叠同样是个非常重要的功能,需要引入如下文件。

最后那个 indent-fold 不要漏了,我就是因为漏了这文件,发现 python 代码无法折叠,debug了很久源码才找到原因,浪费了很多时间!当然,如果用不到的话可以不引入。

import 'codemirror/addon/fold/foldgutter.css'
import 'codemirror/addon/fold/foldcode'
import 'codemirror/addon/fold/foldgutter'
import 'codemirror/addon/fold/brace-fold'
import 'codemirror/addon/fold/comment-fold'
import 'codemirror/addon/fold/markdown-fold'
import 'codemirror/addon/fold/xml-fold'
import 'codemirror/addon/fold/indent-fold'

几个重要的参数如下:

// 代码折叠
gutters: ["CodeMirror-lint-markers","CodeMirror-linenumbers","CodeMirror-foldgutter"
],
foldGutter: true, // 启用行槽中的代码折叠

做完这些配置后,代码就应该可以折叠了,无需额外写 js。

3)以小红点方式显示空格

两个重要的配置:

specialChars :正则表达式,用于描述哪些特殊字符应该被替换为special placeholder。通常用于无法打印的特殊字符。默认为/[\u0000-\u001f\u007f\u00ad\u200b-\u200f\u2028\u2029\ufeff]/。

specialCharPlaceholder :当传入一个与specialChars匹配的字符时,返回一个用于替换的DOM节点。默认为一个红色的点(·)

这个功能也挺有意思的,其实开启的话很简单,只要增加 specialChars 参数,正则中加上空格就行了,但是呢,默认的样式很丑,是个很大很深的红点,如下图所示:

所以呢必须要改,那么查看 codemirror.js 源码,下面贴出关键的部分:

function defaultSpecialCharPlaceholder(ch) {var token = elt("span", "\u2022", "cm-invalidchar");token.title = "\\u" + ch.charCodeAt(0).toString(16);token.setAttribute("aria-label", token.title);return token
}function elt(tag, content, className, style) {var e = document.createElement(tag);if (className) { e.className = className; }if (style) { e.style.cssText = style; }if (typeof content == "string") { e.appendChild(document.createTextNode(content)); }else if (content) { for (var i = 0; i < content.length; ++i) { e.appendChild(content[i]); } }return e
}

根据源码中的 defaultSpecialCharPlaceholder 和 elt 两个方法,我自定义了specialCharPlaceholder 的配置,用于替代默认的空格样式。这里去掉了一些我用不到的,比如非字符串的校验等。然后将大的点替换成了小的点,编码为 \u002e ,自定义的配置如下:

specialChars: /[\u0000-\u001f\u007f-\u009f\u00ad\u061c\u200b-\u200f\u2028\u2029\ufeff\ufff9-\ufffc]/g,
specialCharPlaceholder: function (ch) {let token = document.createElement("span");let content = "\u002e";token.className = "cm-invalidchar";if (typeof content == "string") {token.appendChild(document.createTextNode(content));}token.title = "\\u" + ch.charCodeAt(0).toString(16);token.setAttribute("aria-label", token.title);return token
}

这里specialChars我默认没改的,因为我想要的效果是默认不显示红点,当我想显示红点时再开启。所以我增加了一个开关,当设置为true时, 在 specialChars 的正则中增加 \s (\s表示空格),这样空格就能显示为我想要的小红点了。

并且对 cm-invalidchar 的样式也改了下,颜色修改为淡点的红色,颜色代码为:#909399

最终的样式如下:

4)制表符替换为4个空格

options中增加 extraKeys 配置,修改默认的tab行为。至于替换为几个空格数,是由参数 indentUint 控制的。

代码如下,这段是很久以前刚弄这个编辑器时,从某篇文章中借鉴的。

extraKeys: {Tab: (cm) => {if (cm.somethingSelected()) {      // 存在文本选择cm.indentSelection('add');    // 正向缩进文本} else {                    // 无文本选择cm.replaceSelection(Array(cm.getOption("indentUnit") + 1).join(" "), "end", "+input");  // 光标处插入 indentUnit 个空格}}
}

5)选中单词后,其他相同单词也高亮

需要引入如下文件并增加 option 配置:

import 'codemirror/addon/search/match-highlighter'highlightSelectionMatches: {minChars: 2,trim: true,style: "matchhighlight",showToken: false
},

highlightSelectionMatches中 的 showToken 最好配置为 false,否则在在输入的时候,当前还没输入完的单词也会高亮,很难受,如下图所示:

最终效果如下:

这里高亮的样式我是改过的,为了适应这个主题,我重新了 cm-matchhighlight 的样式,修改了它的背景颜色:

.cm-matchhighlight {background: #848484 !important
}

6)自动补全括号,且光标在括号左右侧时,自动突出匹配的括号

引入如下文件并增加 option 参数:

import 'codemirror/addon/edit/matchbrackets'
import 'codemirror/addon/edit/closebrackets'autoCloseBrackets: true, // 自动闭合符号
matchBrackets: true, // 在光标点击紧挨{、]括号左、右侧时,自动突出显示匹配的括号 }、]

7)其他有用配置

theme:主题样式,我用的monakai,这个就看个人喜好了
mode:这个很重要,不同的语言要使用对应的mode,这样才能有关键字的高亮!mode列表在中英文手册中可以查
lineWrapping:这个要配置为 false,如果配置为true,样式会比较奇怪,原因未知,或许跟我用的monakai主题有关?有知道的人可以告诉我下。
readOnly:决定是否只读
viewportMargin:一次加载多少行,防止文件过大页面卡死
lineNumbers:显示行数当然,还有很多有用的功能,不过我暂时够用了,其他也就懒得继续研究了。

vue-codemirror代码编辑器使用心得和踩坑相关推荐

  1. 百度编辑器(ueditor)踩坑,图片转存无法使用

    原文链接:百度编辑器(ueditor)踩坑,图片转存无法使用 补充 2023-02-03:很多人反馈找不到文中提到的 xss 配置,由于 UE 官网已不再维护,大部分地址都是重定向到 GitHub 仓 ...

  2. android代码混淆个人总结及踩坑

    android代码混淆个人总结及踩坑 前言 公司项目使用组件化开发的形式,需要对自己负责的模块进行一些混淆配置,关于混淆相信做android开发的都或多或少有过一些接触,通过对混淆文件的配置从而将代码 ...

  3. vue2使用Codemirror代码编辑器插件

    让我们先看看需求 :一个有SQL语言提示代码编辑器  一 . 我这里用的是vue2 三种方法,得指定版本号,不指定就是默认最新,版本6以上都是vue3的版本,引入使用会报错 vue3的版本叫vue-c ...

  4. WangEditor富文本编辑器图片上传踩坑之路

    最近由于业务需求,需要用到富文本编辑器,找寻了好久,起初想使用百度的ueditor,但在使用的过程中实在是遇到了太多的坑,于是另外锁定了一款富文本编辑器--wangEditor.这是一款轻量级的富文本 ...

  5. weex-eros+vue Android拍照并预览图片踩坑【小白向】

    [TOC] 最近做一个移动端的手机拍照预览,碰了不少墙,但还是遇到好心人帮助,成功预览.感谢"小豬仔"~ 开干之前,请先阅读 Weex-Eros文档 和 Vue教程 Windows ...

  6. VUE非父子组件通信Bus——公交车踩坑笔记

    抛开父子组件的通讯,对于非父子组件通信,简单的数据交互,使用Bus是非常不错的. 遇到的坑有两个. 1.两个组件的信息交互代码写在哪个生命周期函数中,如果只是点击组件A标签触发函数,然后向界面B传递参 ...

  7. python代码下出现红线_python踩坑系列之导入包时下划红线及报错“No module named”问题...

    python踩坑系列之导入包时下划红线及报错"No module named"问题 使用pycharm编写Python时,自己写了一个包(commontool),在同级另一个路径下 ...

  8. Vue+Element el-table属性row-class-name用法及踩坑

    el-table属性row-class-name用法及踩坑 需求前提:想要给表格的某一行加上不同的background,用来区分当前行的状态 根据官方给出的文档官方文档 在el-table中绑定自定义 ...

  9. vue集成codemirror代码编辑器

    点击上方" 青年码农 "关注 回复"特效源码"可获取各种资料 CodeMirror是一个用 JavaScript 为浏览器实现的通用文本编辑器.它专门用于编辑代 ...

最新文章

  1. 实践微服务六年,我获得了这些心得体会
  2. 查看依赖树_Python中的依赖关系处理
  3. centos重启网络失败Job for network.service failed,ping不通网络
  4. iphone 有关(maybe you meant: _kSecClass$non_lazy_ptr)
  5. [SHOI2014] 概率充电器
  6. 计算机是如何启动的?从未上电到操作系统启动
  7. Leetcode题解(十三)
  8. mac下载的api文档怎么_Python调用百度API实现语音识别(二)
  9. 主程序员团队与敏捷开发的联合应用(小型敏捷团队管理)
  10. 深入理解原型模式 ——通过复制生成实例
  11. PHP文件操作 读取与写入
  12. Skype for business企业语音配置之二创建拨号计划
  13. 利用Linux系统实现VLAN间的单臂路由及安全网关的功能
  14. movielens1M数据处理
  15. PMP课程笔记:第11章 项目风险管理
  16. 接着,运营基础知识(福利篇)
  17. 在 sysservers 中找不到服务器,在 sys.servers 中找不到服务器的解决办法,自己解决的...
  18. 好用的在线音乐网站,有这5个就够了(收藏备用)
  19. 电脑上总显示宽带连接服务器怎么办啊,电脑显示宽带已连接但网页打不开怎么办...
  20. 【Pyecharts】20W条淘宝文胸商品评论数据可视化~

热门文章

  1. 7、SHA1加密算法
  2. 第十届“中国软件杯”参赛项目总结
  3. linux系统常用的简单操作命令
  4. rsa算法_RSA算法实现过程
  5. ProSci 艾美捷14 3 3 zeta抗体说明书
  6. Win11的两个实用技巧系列之如何关闭文字热门搜索、任务栏上的应用
  7. C语言与C++的区别(一)
  8. iis服务器证书,Internet Information Services (IIS) 服务器证书安装说明
  9. 中国临沂 盛世启航 盛世昊通华东系统临沂启动会隆重召开
  10. python图像_Python图像处理库(PIL)