vue2+codemirror代码渲染,实现滚动到指定行(三 滚动指定行)

22 篇文章 2 订阅
1 篇文章 0 订阅

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>

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值