引用的两种方式
<template>
<div class="js-editor">
<textarea ref="textarea" v-model="value" />
</div>
</template>
<script>
import sqlFormatter from 'sql-formatter'
import CodeMirror from 'codemirror'
import 'codemirror/lib/codemirror.css'
import 'codemirror/addon/hint/show-hint.css'
import 'codemirror/theme/idea.css'
import 'codemirror/addon/edit/closebrackets.js' // 在键入时自动关闭括号和引号
import 'codemirror/lib/codemirror'
import 'codemirror/mode/sql/sql'
import 'codemirror/addon/hint/show-hint' // 自动提示
import 'codemirror/addon/hint/sql-hint'
export default {
name: 'Editor',
/* eslint-disable vue/require-prop-types */
props: ['value', 'hintobj', 'readOnly'],
data() {
return {
editor: null
}
},
watch: {
value: {
immediate: true,
handler(value) {
if (this.editor) {
if (value === undefined) {
this.editor.setValue('')
} else {
this.editor.setValue(sqlFormatter.format(this.value))
}
setTimeout(() => {
this.editor.refresh()
}, 100)
}
}
},
hintobj(val) {
// 动态设置tables参数
this.editor.setOption('hintOptions', {
completeSingle: false,
// 自定义提示选项
tables: val
})
}
},
mounted() {
const _this = this
_this.editor = CodeMirror.fromTextArea(this.$refs.textarea, {
mode: 'text/x-sql',
theme: 'idea', // 用于设置编辑器样式的主题
lineNumbers: true, // 是否在编辑器的左侧显示行号
line: true,
readOnly: this.readOnly,
autoCloseBrackets: true, // 在键入时自动关闭括号和引号
smartIndent: true,
extraKeys: { // 自动补全的按键事件
"'a'": completeAfter,
"'b'": completeAfter,
"'c'": completeAfter,
"'d'": completeAfter,
"'e'": completeAfter,
"'f'": completeAfter,
"'g'": completeAfter,
"'h'": completeAfter,
"'i'": completeAfter,
"'j'": completeAfter,
"'k'": completeAfter,
"'l'": completeAfter,
"'m'": completeAfter,
"'n'": completeAfter,
"'o'": completeAfter,
"'p'": completeAfter,
"'q'": completeAfter,
"'r'": completeAfter,
"'s'": completeAfter,
"'t'": completeAfter,
"'u'": completeAfter,
"'v'": completeAfter,
"'w'": completeAfter,
"'x'": completeAfter,
"'y'": completeAfter,
"'z'": completeAfter,
"'.'": completeAfter,
'Ctrl-Enter': 'autocomplete'
},
hintOptions: {
completeSingle: false,
tables: _this.hintobj // sql类型下自定义提示选项使用tables
// tables结构示例: {'user': ['name', 'sex', 'id'], 'student': ['b_id', 'name']}
},
lineWrapping: true // 是否应滚动或换行以显示长行
})
// 对应按键下调用的自动提示方法
function completeAfter(cm, pred) {
if (!pred || pred()) {
setTimeout(function() {
if (!cm.state.completionActive) {
cm.showHint({
completeSingle: false
})
}
}, 100)
}
return CodeMirror.Pass
}
_this.editor.setValue(sqlFormatter.format(this.value))
},
methods: {
}
}
</script>
// 搜索功能
// find:Ctrl-F (PC), Cmd-F (Mac)
// findNext:Ctrl-G (PC), Cmd-G (Mac)
// findPrev:Shift-Ctrl-G (PC), Shift-Cmd-G (Mac)
// replace:Shift-Ctrl-F (PC), Cmd-Alt-F (Mac)
// replaceAll:Shift-Ctrl-R (PC), Shift-Cmd-Alt-F (Mac)
import 'codemirror/addon/dialog/dialog.css'
import 'codemirror/addon/dialog/dialog'
import 'codemirror/addon/search/searchcursor'
import 'codemirror/addon/search/search'
import 'codemirror/addon/search/jump-to-line'
import 'codemirror/addon/search/matchesonscrollbar'
import 'codemirror/addon/search/match-highlighter'
// 代码提示功能 具体语言可以从 codemirror/addon/hint/ 下引入多个
import 'codemirror/addon/hint/show-hint.css';
import 'codemirror/addon/hint/show-hint';
import 'codemirror/addon/hint/sql-hint';
// 高亮行功能
import 'codemirror/addon/selection/active-line'
import 'codemirror/addon/selection/selection-pointer'
// 调整scrollbar样式功能
import 'codemirror/addon/scroll/simplescrollbars.css'
import 'codemirror/addon/scroll/simplescrollbars'
// 自动括号匹配功能
import 'codemirror/addon/edit/matchbrackets'
// 全屏功能 由于项目复杂,自带的全屏功能一般不好使
import 'codemirror/addon/display/fullscreen.css'
import 'codemirror/addon/display/fullscreen'
// 显示自动刷新
import 'codemirror/addon/display/autorefresh'
// 多语言支持?
import 'codemirror/addon/mode/overlay'
import 'codemirror/addon/mode/multiplex'
// 代码段折叠功能
import 'codemirror/addon/fold/foldcode'
import 'codemirror/addon/fold/foldgutter'
import 'codemirror/addon/fold/foldgutter.css'
import 'codemirror/addon/fold/brace-fold'
import 'codemirror/addon/fold/comment-fold'
import 'codemirror/addon/fold/xml-fold.js';
import 'codemirror/addon/fold/indent-fold.js';
import 'codemirror/addon/fold/markdown-fold.js';
import 'codemirror/addon/fold/comment-fold.js';
在methods中自定义代码实现方法:
/**
1. 第一个入参cmInstance指的是codeMirror实例,第二个是配置中的的hintOptions值。
2. 从cmInstance中getCursor指的是获取光标实例,光标实例里有行数、列数。
3. 可以从cmInstance的getLine方法里传入一个行数,从而获取行中的字符串。
4. token对象是cmInstance对光标所在字符串进行提取处理,从对应语言的类库中判断光标所在字符串的类型,方便hint提示。token中包含start、end、string、type等属性,start和end指的是光标所在字符串在这一行的起始位置和结束位置,string是提取的字符串,type表示该字符串是什么类型(keyword/operator/string等等不定)
5. 下面方法中返回的结果体意思是:下拉列表中展示hello和world两行提示,from和to表示当用户选择了提示内容后,这些提示内容要替换编辑区域的哪个字符串。方法中的代码含义是替换token全部字符串。
*/
handleShowHint(cmInstance, hintOptions) {
let cursor = cmInstance.getCursor();
let cursorLine = cmInstance.getLine(cursor.line);
let end = cursor.ch;
let start = end;
let token = cmInstance.getTokenAt(cursor)
console.log(cmInstance, cursor, cursorLine, end, token)
// console.log(hintOptions.tables)
// return hintOptions.tables;
return {
list: ["hello","world"],
from: {ch: token.start, line: cursor.line},
to: {ch: token.end, line: cursor.line}
};
}
修改codemirror下的option配置:
{ // 省略其他配置项...
hintOptions: {
completeSingle: false,
hint: this.handleShowHint
}
}
其他高级用法请参考:https://blog.gavinzh.com/2020/12/13/codemirror-getting-started/