• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

测开前端系列 - Vue + codemirror 代码行自定义渲染(renderLine)

武飞扬头像
树叶小记
帮助26

背景

各个公司有各个公司的技术栈,在之前公司强大的前端脚手架的支持下,成功的运用react ts依赖codemirror,实现了一个在线编辑工具(主要目的是为了增强代码覆盖率的报告展示能力)。后面因为“大环境”的原因,来到了新的公司,并需要在vue的环境下重新造一回轮子。当然我想用最小成本,复用之前大部分的codemirror自定义渲染相关的代码。于是在vue的社区中,找到了一个vue-codemirror的依赖。但是因为语法封装上的差异,并没法一摸一样的使用之前的方式进行复用。通过度娘,找到的信息,又不能完全解决问题,所以仅用此文,来记录这些细节。

vue的lib引用

首先是找到依赖并进行lib导入。这块度娘还是有的。我主要使用的方式如下:

npm install vue-codemirror

在main.js中引入codemirror


import VueCodeMirror from 'vue-codemirror';
import 'codemirror/lib/codemirror.css';
import 'codemirror/theme/idea.css';
import 'codemirror/mode/clike/clike.js';

Vue.use(VueCodeMirror);

之后我们就可以顺利的使用codemirror了。

codemirror的renderLine

codemirror的renderLine是一个很强大的自定义渲染代码展示方法。它的内置参数有整个codemirror的实例,进行渲染时某一行的句柄以及某一行的完整dom元素。在我的案例中,主要需要在展示代码的基础上附加代码行的背景色,并为每一行代码添加具体的提交改动时间。

学新通技术网

之前直接使用codemirror的方式下,可以直接使用onRenderLine的属性来使用自定义的renderLine方法:

 <CodeMirror
    className={styles.mirrorCode}
    options={
      {
        mode: 'text/x-java',
        theme: 'idea',
        lineNumbers: true,
        lineWrapping: true,
        showCursorWhenSelecting:true,
        // viewportMargin: 20,
        readOnly:true,
        selectionPointer:true,
        styleActiveLine: true,
      }
    }
    onRenderLine={(editor:any, line:any, elem:any) =>
      this.renderLine(editor, line, elem)}
    value={fileContent}
    editorDidMount={(editor:any) => this.handleEditMount(editor)}
    onChange={(edit:any) => { console.log('内容改动了'); }}
  />

但是在vue-codemirror中没有了这个属性。

<template>
  <el-card v-loading="loading">
    <h2>{{`${appName} - ${path}`}}</h2>
    <codemirror
      ref="covCode"
      class="mirrorCode"
      :options="options"
      :value="content"
    />
  </el-card>
</template>

找度娘,查codemirror manual文档,最后发现可以通过codemirror的对象进行renderLine事件绑定,从而达到之前react方式的效果。

首先,可以通过组建的创建事件设置全局的codemirror引用:(created,mounted)

this.codemirror = this.$refs.covCode.codemirror;

其次,可以给codemirror绑定renderLine的event事件:

 this.codemirror.on("renderLine", this.renderLine);

最后,就是重新把renderline的代码进行编辑就可以了

// 渲染方法
   renderLine(editor, line, elem) {
      const lineNumber = line.lineNo();
      this.gitRender(lineNumber, elem);
      this.coverRender(lineNumber, elem);
    },
    // 针对某一行渲染代码的提交更改情况
    gitRender(lineNumber, elem) {
      const commit = this.lines[lineNumber];
      if (!commit) {
        return;
      }
      const leftNode = document.createElement('span');
      leftNode.style = 'padding-right:5px;width:330px;display:inline-block;';

      const gitNode = document.createElement('span');
      const content = new Date(commit.updateDate).toLocaleString()   " "   commit.author;
      gitNode.textContent = this.cutStringByLength(content, 30);
      gitNode.style = 'width:260px;display:inline-block;';

      leftNode.appendChild(gitNode);
      const dt = new Date;
      // 新旧代码提醒
      if ((dt.getTime() - new Date(commit.updateDate).getTime())
        < 24 * 60 * 60 * 1000 * 14) {
        const strongNew = document.createElement('strong');
        strongNew.textContent = ' New ';
        strongNew.style = 'color:red';
        gitNode.appendChild(strongNew);
      }
      if (elem.children[0]) {
        elem.insertBefore(leftNode, elem.children[0]);
      } else {
        elem.appendChild(leftNode);
      }
    },
    // 针对某一行渲染背景颜色
    coverRender(lineNumber, elem) {
      const status = this.covLines[lineNumber   1];
      if (status && status !== 0) {
        switch (status) {
          case 1:
            elem.setAttribute("style", (elem.getAttribute("style") || '')   "background: rgba(255, 179, 185, 0.42);")
            break;
          case 2:
            elem.setAttribute("style", (elem.getAttribute("style") || '')   "background: rgba(139, 195, 74, 0.51);")
            break;
          case 3:
            elem.setAttribute("style", (elem.getAttribute("style") || '')   "background: rgba(255, 152, 0, 0.43);")
            break;
          default:
            break;
        }
      }
    }

效果图:

学新通技术网

最后

通过上述的这种方式,绝大多数数的代码都可以从之前react版本,轻松快捷的转移到vue 上。codemirror在在线编辑这块上确实挺好用,如果有需要可以使用上cdn版本,让前端体验上可以更好。在其他的一些属性,内置对象,内置方法上有需要可以参考manual进行查找,合理使用。

微信公众号:树叶小记

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanghhebj
系列文章
更多 icon
同类精品
更多 icon
继续加载