最近工作中需要用到网页端代码编辑器。在此使用code-mirror插件作为提供者,以下总结一些遇到的问题及解决方案:
参考手册:
vue-codemirror 地址: https://github.com/codemirror/CodeMirror.
codemirror 中文API文档:https://olindk.gitbooks.io/codemirror/content/commands.html
描述 | |
---|---|
cm | 以下cm皆为code-mirror简称 |
… | 以下…皆为代码省略 |
1.无法自动加载配置文件,必须要点击一下code-mirror
区域方可加载
-
点击前
-
点击后:
-
解决方案:
抓包后发现数据已经获取,猜测是cm没有执行自动刷新组件导致,在option内添加autoRefresh: true
import 'codemirror/addon/display/autoRefresh.js'
cmOptions: { theme: 'xml', mode: '', readOnly: false, autoRefresh: true, autofocus: true, viewportMargin: 1000, //指定当前滚动到视图中内容上⽅和下⽅要渲染的⾏数 lineNumbers: true, // 是否显示行号 lineWrapping: true // 是否应滚动或换行以显示长行 }
2.code-mirror和tab组件一起使用时,导致行号区域重叠
-
异常时:
-
解决方案:
点击切换tab时,需要刷新cm组件,否则有一定几率会造成行号区域重叠handleClick(tab, event){ if (tab.name === 'selfDefineBtn') { this.open(tab.index) } else { this.$nextTick(() => { // refresh code-mirror let that = this.$refs.[this.activeName + 'mirror'][0].editor that.refresh(); }) } }
-
解决后:
3.code-mirror 组件中自定义方法
由于业务规则问题,保存配置文件时,会检测配置内容是否符合规则,若存在无法识别的语法则会提示错误信息并返回错误行号。
需要根据错误行号在textarea区域高亮显示错误行。
cm组件内部已经考虑到了这点,提供了CodeMirror.defineExtension
接口实现自定义的方法。
参考active-line
高亮插件的原理,传入行号(from, to)
,实现高亮效果,贴上代码:
active-line
部分源代码:var WRAP_CLASS = "CodeMirror-activeline"; var BACK_CLASS = "CodeMirror-activeline-background"; var GUTT_CLASS = "CodeMirror-activeline-gutter"; CodeMirror.defineOption("styleActiveLine", false, function(cm, val, old) { ... function clearActiveLines(cm) { for (var i = 0; i < cm.state.activeLines.length; i++) { cm.removeLineClass(cm.state.activeLines[i], "wrap", WRAP_CLASS); cm.removeLineClass(cm.state.activeLines[i], "background", BACK_CLASS); cm.removeLineClass(cm.state.activeLines[i], "gutter", GUTT_CLASS); } } function updateActiveLines(cm, ranges) { var active = []; ... cm.operation(function() { clearActiveLines(cm); for (var i = 0; i < active.length; i++) { cm.addLineClass(active[i], "wrap", WRAP_CLASS); cm.addLineClass(active[i], "background", BACK_CLASS); cm.addLineClass(active[i], "gutter", GUTT_CLASS); } cm.state.activeLines = active; }); } });
- 自定义新增方法:
var WRAP_ERROR_CLASS = "CodeMirror-error-activeline"; var BACK_ERROR_CLASS = "CodeMirror-error-activeline-background"; var GUTT_ERROR_CLASS = "CodeMirror-error-activeline-gutter"; CodeMirror.defineOption("styleActiveLine", false, function(cm, val, old) { ... //添加监听器,焦点在错误行时取消错误高亮样式 cm.on("beforeSelectionChange", clearErrorLines); function clearAllActiveLines(cm) { clearActiveLines(cm); clearErrorLines(cm); } function clearErrorLines(cm) { for (var i = 0; i < cm.state.activeLines.length; i++) { cm.removeLineClass(cm.state.activeLines[i], "wrap", WRAP_ERROR_CLASS ); cm.removeLineClass(cm.state.activeLines[i], "background", BACK_ERROR_CLASS ); cm.removeLineClass(cm.state.activeLines[i], "gutter", GUTT_ERROR_CLASS ); } } function updateActiveLines(cm, ranges) {...} /** * from: start line * to: end line */ const setErrorLines = function(cm, from, to) { let active = [] if (!from || !to) return clearAllActiveLines(cm); for (let i = from; i <= to; i++) { let line = cm.getLineHandleVisualStart(i); this.addLineClass(line, "wrap", WRAP_ERROR_CLASS ); this.addLineClass(line, "background", BACK_ERROR_CLASS ); this.addLineClass(line, "gutter", GUTT_ERROR_CLASS ); } cm.state.activeLines = active; }; // 自定义方法 CodeMirror.defineExtension("setErrorLines", setErrorLines); });
- 效果展示:
4.自动补全括号,且光标在括号左右侧时,自动突出匹配的括号
import 'codemirror/addon/edit/matchbrackets'
import 'codemirror/addon/edit/closebrackets'
cmOptions: {
theme: 'xml',
mode: '',
readOnly: false,
autoRefresh: true,
autofocus: true,
viewportMargin: 1000, //指定当前滚动到视图中内容上⽅和下⽅要渲染的⾏数
lineNumbers: true, // 是否显示行号
lineWrapping: true, // 是否应滚动或换行以显示长行
autoCloseBrackets: true, // 自动闭合符号
matchBrackets: true, // 在光标点击紧挨{、]括号左、右侧时,自动突出显示匹配的括号 }、]
}
后续出现问题还会继续补充。
仅作为使用总结记录,望诸君共勉