vue2+codemirror代码渲染,当代码量过大时,在几千行的代码中找到所需的方法类比较困难。这时我们需要跳转到具体方法类,代码滚动到方法类所在的代码行。
这里需要先把光标指向到指定行,再滚动到该行,
亲测好用
scrollToLine(n) {
// 将光标设置到第n行的第一个字符
this.codemirror.setCursor({ line: n + 20, ch: 0 })
// 滚动到该行
this.codemirror.scrollIntoView()
},
完整代码:
<template>
<div class="code-edit fullscreenContent">
<i v-if="!isFullscreen" class="el-icon-full-screen fullScreenIcon" title="进入全屏" style="font-size: 15px" @click="clickFun"></i>
<img v-if="isFullscreen" class="fullScreenIcon" title="退出全屏" src="@/assets/miniscreen.png" @click="clickFun" />
<codemirror ref="codeMirror" :value="value" :options="cmOptions" />
</div>
</template>
<script>
import screenfull from 'screenfull'
import { codemirror } from 'vue-codemirror'
import 'codemirror/mode/clike/clike'
// cm-setting.js
// 组件样式
import 'codemirror/lib/codemirror.css'
// 主题
import 'codemirror/theme/eclipse.css'
// import 'codemirror/theme/monokai.css'
// html代码高亮
import 'codemirror/mode/htmlmixed/htmlmixed.js'
// 语言模式
import 'codemirror/mode/javascript/javascript.js'
import 'codemirror/mode/css/css.js'
import 'codemirror/mode/xml/xml.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'
export default {
name: 'Editor',
components: {
codemirror,
},
props: {
value: '',
covLines: [],
noCovLines: [],
},
data() {
return {
codemirror: null,
code: '// Your Java code here',
cmOptions: {
autoRefresh: true, // 重点是这句,为true
value: '', // 初始内容
mode: 'text/x-java', //实现Java代码高亮
tabSize: 4, // tab的空格宽度
styleActiveLine: true, // 设置光标所在行高亮true/false
lineNumbers: true, //显示行号
theme: 'eclipse', //设置主题cobalt/monokai
// json: true,
readOnly: 'nocursor', // 设置为只读true/false;也可设置为"nocursor"失去焦点
lineWrapping: false,
foldGutter: true,
gutters: [
'CodeMirror-lint-markers', //代码错误检测
'CodeMirror-linenumbers',
'CodeMirror-foldgutter', //展开收起
],
},
// 全屏展示
isFullscreen: false,
}
},
mounted() {
this.codemirror = this.$refs.codeMirror.codemirror
// this.codemirror.on('renderLine', this.renderLine)
this.coverRender()
setTimeout(() => {
this.scrollToLine(187)
}, 100)
// 当前是否全屏
document.addEventListener('fullscreenchange', (v) => {
this.isFullscreen = screenfull.isFullscreen
})
window.addEventListener('keydown', function (event) {
// 禁掉F11的全屏的默认事件,不会禁止F11的退出全屏
const e = event || window.event
if (e && e.keyCode === 122) {
e.preventDefault()
}
})
},
methods: {
// 渲染方法
renderLine(editor, line, elem) {
const lineNumber = line.lineNo()
this.coverRender(lineNumber, elem)
},
// 针对某一行渲染背景颜色
coverRender(lineNumber, elem) {
// let line = lineNumber + 1
// if (this.covLines.includes(line)) {
// elem.setAttribute('style', (elem.getAttribute('style') || '') + 'background: #ccffcc;')
// } else if (this.noCovLines.includes(line)) {
// this.codemirror.addLineClass(line, 'text', 'notcover-class')
// elem.setAttribute('style', (elem.getAttribute('style') || '') + 'background: #ffd7d5;')
// }
this.covLines.map((item) => {
this.codemirror.addLineClass(item - 1, 'text', 'cover-class')
})
this.noCovLines.map((item) => {
this.codemirror.addLineClass(item - 1, 'text', 'notcover-class')
})
},
scrollToLine(n) {
// 将光标设置到第n行的第一个字符
this.codemirror.setCursor({ line: n + 20, ch: 0 })
// 滚动到该行
this.codemirror.scrollIntoView()
},
// 全屏/非全屏展示
clickFun() {
this.isFullscreen = !this.isFullscreen
const element = document.getElementsByClassName('fullscreenContent')[0] //指定全屏区域元素
if (this.isFullscreen) {
// element.requestFullscreen()
this.requestFullScreen(element)
} else {
this.cancelFullScreen()
}
},
// 全屏,兼容浏览器
requestFullScreen(element) {
if (element.requestFullscreen) element.requestFullscreen()
else if (element.msRequestFullscreen) element.msRequestFullscreen()
else if (element.mozRequestFullScreen) element.mozRequestFullScreen()
else if (element.webkitRequestFullscreen) element.webkitRequestFullscreen()
},
// 取消全屏,兼容浏览器
cancelFullScreen() {
if (document.exitFullscreen) document.exitFullscreen()
else if (document.msExitFullscreen) document.msExitFullscreen()
else if (document.mozCancelFullScreen) document.mozCancelFullScreen()
else if (document.webkitExitFullscreen) document.webkitExitFullscreen()
},
},
}
</script>
<style lang="scss">
.code-edit {
height: 100%;
.vue-codemirror,
.CodeMirror {
height: 100%;
}
/* 添加自定义的高亮样式 */
.my-highlight-class {
background-color: rgba(255, 128, 128, 0.4);
}
.CodeMirror pre.CodeMirror-line,
.CodeMirror pre.CodeMirror-line-like {
font-family: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace;
font-size: 12px;
word-wrap: anywhere;
white-space: pre-wrap;
}
.cm-s-eclipse span.cm-property {
line-height: 20px;
color: #303030;
}
.cm-s-eclipse span.cm-variable {
color: #303030;
}
.fullScreenIcon {
position: absolute;
top: 5px;
right: 15px;
z-index: 1;
font-size: 15px;
cursor: pointer;
}
}
// 已覆盖
.CodeMirror pre.CodeMirror-line.cover-class {
background: rgba(9, 245, 9, 0.2);
}
// 未覆盖
.CodeMirror pre.CodeMirror-line.notcover-class {
background: rgba(243, 64, 55, 0.2);
}
</style>