项目需要,使用vue-codemirror写了个在线编辑代码的组件,在此处记录下
该组件具备代码提示,代码高亮、代码折叠,自动闭合括号等功能,
首先进行安装
cnpm i vue-codemirror
接下来是组件代码
<template>
<div>
<codemirror
v-model="codeSnippets"
:options="cmOptions"
@ready="onCmReady"
/>
</div>
</template>
<script>
import { codemirror } from 'vue-codemirror'
import { mapState } from 'vuex'
// require styles
import 'codemirror/lib/codemirror.css'
import 'codemirror/mode/javascript/javascript'
import 'codemirror/mode/htmlembedded/htmlembedded'
import 'codemirror/mode/htmlmixed/htmlmixed'
import 'codemirror/theme/monokai.css'
import 'codemirror/addon/hint/show-hint.css'
import 'codemirror/addon/hint/show-hint.js'
import 'codemirror/addon/hint/javascript-hint.js'
// 折叠
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'
// 搜索
import 'codemirror/addon/scroll/annotatescrollbar.js'
import 'codemirror/addon/search/matchesonscrollbar.js'
import 'codemirror/addon/search/match-highlighter.js'
import 'codemirror/addon/search/jump-to-line.js'
// 提示
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'
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/search/match-highlighter'
import 'codemirror/addon/edit/matchbrackets'
import 'codemirror/addon/edit/closebrackets'
export default {
components: {
codemirror
},
data() {
return {
codeSnippets: `//Ctrl-S 或者 F5 执行JS
//Ctrl-Z撤销
//Ctrl-Y撤销回退
//Ctrl-F执行查询
`,
cmOptions: {
tabSize: 2,
mode: 'text/html',
lineNumbers: true,
viewportMargin: Infinity, // 处理高度自适应时搭配使用
highlightDifferences: true,
autoCloseBrackets: true,
indentUnit: 2,
smartIndent: true,
theme: 'monokai',
foldGutter: true,
lineWrapping: true,
allowDropFileTypes: ['text/html'],
dragDrop: true,
gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter', 'CodeMirror-lint-markers'],
extraKeys: {
'Ctrl-S': (editor, e) => {
this.$emit('run')
},
'F5': (editor, e) => {
this.$emit('run')
},
'Ctrl-Z': function(cm) {
cm.undo()
},
'Ctrl-Y': function(cm) {
cm.redo()
},
'Ctrl-Shift-\\': 'indentAuto',
'Ctrl-/': 'toggleComment'
},
autocorrect: true,
spellcheck: true,
autoCloseTags: true,
matchTags: { bothTags: true },
matchBrackets: true, // 在光标点击紧挨{、]括号左、右侧时,自动突出显示匹配的括号 }、]
styleSelectedText: true,
styleActiveLine: true,
highlightSelectionMatches: {
minChars: 2,
trim: true,
style: 'matchhighlight',
showToken: false
}
}
}
},
computed: {
...mapState(['code'])
},
watch: {
code(value) {
this.codeSnippets = value
}
},
mounted() {
document.querySelector('.vue-codemirror').addEventListener('keydown', e => {
e.stopPropagation()
})
},
methods: {
onCmReady(cm) {
cm.on('inputRead', (cm, obj) => {
if (obj.text && obj.text.length > 0) {
const c = obj.text[0].charAt(obj.text[0].length - 1)
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
cm.showHint({ completeSingle: false })
}
}
})
},
setCode(code) {
this.codeSnippets = code
},
getCode() {
return this.codeSnippets
}
}
}
</script>
<style lang="less">
.CodeMirror{
font-family: monospace;
color: black;
text-align: left;
width: calc(100% + 1px);
height: calc(100vh - 40px);
box-sizing: border-box;
direction: ltr;
}
</style>