Vue2 集成 CodeMirror 实现公式编辑、块状文本编辑,TAG标签功能

news2024/11/14 15:01:23

效果图

 安装codemirror依赖

本示例为Vue2项目,安装低版本的依赖

npm i codemirror@5.65.12
npm i vue-codemirror@4.0.6

实现

实现代码如下,里边涉及到的变量和函数自行替换即可,没有其他复杂逻辑。

<template>
  <div class="picker">
    <div class="code-edit">
      <div class="top-title">公式</div>
      <codemirror
              ref="codeEditor"
              v-model="formulaStr"
              :options="cmOptions"
              @input="codeMirrorChange"
      ></codemirror>

    </div>
    <el-button
            size="mini"
            icon="el-icon-setting"
            @click="insertContent('表单4', 'variable')"
    >添加变量
    </el-button
    >
    <el-button
            size="mini"
            icon="el-icon-setting"
            @click="insertContent('SUM', 'func')"
    >添加函数
    </el-button
    >
  </div>

</template>

<script>
import {codemirror} from "vue-codemirror";
import "codemirror/lib/codemirror.css";
import "codemirror/theme/idea.css";

export default {
  components: {codemirror},
  data() {
    return {
      cmOptions: {
        // 语言及语法模式
        mode: 'text/javascript',
        // 主题
        theme: "idea",
        // 显示函数
        line: true,
        lineNumbers: false,
        // 软换行
        lineWrapping: true,
        // tab宽度
        tabSize: 4,
      },
      lang: 'javascript',
      formulaStr: "表单 表单1 * 表单11*表单12+SUM(1,2) AVG(99,21) IF()",
    };
  },
  computed: {
    editor() {
      return this.$refs.codeEditor.codemirror;
    }
  },
  mounted() {
    this.focus(this.formulaStr)
    this.autoMarkText()
  },
  methods: {
    codeMirrorChange() {
      //获取 editor 的内容
      console.log("content1: " + this.formulaStr);
      console.log("content2: " + JSON.stringify(this.editor.getValue()));
    },
    addFormula(content, type) {
      this.insertContent(content, type)
    },
    /**
     * editor 中的对内容进行处理
     * @param value
     * @param type variable | func,variable为表单变量,需标记,func 为函数,也需要做标记
     */
    insertContent(value, type) {
      const from = this.editor.getCursor();
      if (type === 'variable') {
        this.editor.replaceSelection(value);
        const to = this.editor.getCursor();
        this.markText(from, to, value, 'cm-field');
      } else if (type === 'func') {
        this.editor.replaceSelection(`${value}()`);
        const to = this.editor.getCursor();
        this.markText(from, {line: to.line, ch: to.ch - 2}, value, 'cm-func');
        this.editor.setCursor({line: to.line, ch: to.ch - 1});
      } else if (typeof value === 'string') {
        this.editor.replaceSelection(value);
      }
      this.editor.focus();
    },

    autoMarkText() {
      if (this.formulaStr) {
        this.autoMark(this.formulaStr);
        this.focus(this.formulaStr);
      }
    },
    focus(value) {
      this.editor.setCursor({
        line: 0,
        ch: value ? value.length : 0
      });
      this.editor.focus()
    },
    markText(from, to, label, className) {
      if (className === void 0) {
        className = "cm-func";
      }
      let text = document.createElement("span");
      text.className = className;
      text.innerText = label;
      this.editor.markText(from, to, {
        atomic: true,
        replacedWith: text,
      });
    },
    /**
     * 解析 editor 的内容,分别对表单变量和函数进行标记
     */
    autoMark() {
      const editor = this.editor;
      const lines = editor.lineCount();
      for (let line = 0; line < lines; line++) {
        const content = editor.getLine(line);
        // 标记函数调用,匹配一个或多个连续的大写字母,后面可以有任意数量的空白字符,再紧跟一个左括号
        content.replace(/([A-Z]+)\s*\(/g, (_, func, pos) => {
          this.markText({line: line, ch: pos}, {line: line, ch: pos + func.length}, func, 'cm-func');
          return _;
        });
        // 标记表单变量,这应该是动态获取,自行替换即可
        let vars = ["表单", "表单1", "表单11", "表单12"];
        vars.forEach(v => {
          let from = 0;
          let idx = -1;
          while (~(idx = content.indexOf(v, from))) {
            this.markText({line: line, ch: idx}, {line: line, ch: idx + v.length}, v, 'cm-field');
            from = idx + v.length;
          }
        });
      }
    },
  },
};
</script>

<style lang="less" scoped>
.picker {
  height: 525px;
  text-align: left;
  width: 50%;
  margin: 0 auto;
  .code-edit {
    height: 240px;
    border-radius: 6px;
    border: 1px solid #e8e9eb;
  }
}
.top-title {
  background-color: #fafafa;
  height: 30px;
  vertical-align: center;
  line-height: 30px;
  padding-left: 10px;
  border-radius: 4px 4px 0 0;
  border-bottom: none;
}
/deep/ .CodeMirror {
  height: 200px !important;
  /*表单变量样式*/
  .cm-field {
    background: #007bff;
    padding: 3px 5px;
    border-radius: 3px;
    color: #fff;
    margin: 0 1px;
  }
  /*函数样式*/
  .cm-func {
    font-weight: bold;
    color: #ae4597;
    line-height: 14px;
    margin: 0 1px;
    padding: 0 2px;
  }
  .CodeMirror-scroll {
    width: 100%;
  }
}

</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/959649.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

排盘程序算法探寻举例(陆先生八字)

算法实现&#xff1a; 1.庚生未月&#xff0c;燥土不能生金&#xff0c;日支申金为日主墙根&#xff0c;月干辛金比劫透出傍身&#xff0c;月干强。年干甲木自做寅木强根&#xff0c;又得月支乙木中气&#xff0c;甲木强旺有力&#xff0c;时干丙火七杀得未土余气&#xff0c;…

VMware Aria Operations SSH 身份验证绕过漏洞 (CVE-2023-34039)

zhi.oscs1024.com​​​​​ 漏洞类型身份验证不当发现时间2023-08-30漏洞等级严重MPS编号MPS-d9wr-56qmCVE编号CVE-2023-34039漏洞影响广度广 漏洞危害 OSCS 描述VMware Aria Operations for Networks 是 VMware 公司提供的一款网络可视性和分析工具&#xff0c;用于优化网络…

链表形式队列

&#x1f308;队列相关概念 1.储存了数据的节点从一端&#xff08;队尾&#xff09;进入队列&#xff08;入队尾插&#xff09;&#xff0c;从另一端&#xff08;队头&#xff09;出队列&#xff08;出队头删&#xff09;&#xff0c;先进先出。进行插入操作的一端称为队尾&am…

软件测试Day4|软件测试理论02

目录 6. 测试用例基础6.1 测试用例的定义6.2 测试用例要素6.3 测试用例设计和编写的作用 7. 黑盒测试用例设计方法7.1 用例设计方法分类7.2 测试数据选择7.2.1 等价类划分&#xff08;1&#xff09;等价类划分原理&#xff08;2&#xff09;确定等价类的原则&#xff08;3&…

群晖DS923+扩展ECC 64G内存

1 有必要上64G吗&#xff1f; 如果你不运行大型应用以及安装的套件不多&#xff0c;并且不使用虚拟机&#xff0c;确实没有太大必要。 但是大内存除了这些用处&#xff0c;还会被系统作为缓存使用。在资源监控中查看内存结构&#xff0c;虽然内存利用率只有4%&#xff0c;但缓存…

企业供应链数字化怎么做?企业数字化供应链流程落地方式

什么是供应链&#xff1f;简单来说&#xff0c;供应链是围绕客户需求&#xff0c;以提高产品流通各个环节的效率为目标&#xff0c;通过资源整合的方式来实现产品从设计、生产到销售、服务整个环节的组织形态。如同人工智能、区块链、5G等技术的发展带来的各种行业变化&#xf…

mov怎么改成mp4?跟我一起操作吧

mov怎么改成mp4&#xff1f;mov因为并不是一种常见的视频文件格式&#xff0c;因此大家对这种视频文件可能知道的并不多&#xff0c;但如果你是用的是苹果手机&#xff0c;那么你会发现苹果手机拍摄的视频转移到电脑上后就是mov格式的&#xff0c;因为mov格式的视频并没有受到大…

运算放大器典型应用(一)

这里写目录标题 一、反向比例运算电路怎么优化&#xff1f;平衡电阻的讨论 二、同向比例运算电路三、电压跟随器重要事项 四、加法运算电路反向加法同向加法 五、减法运算电路专用减法器 六、积分电路微分电路七、对数指数运算电路八、测量放大电路&#xff08;仪表放大电路&am…

低代码概念——初步认识低代码

随着数字化转型和软件需求的不断增长&#xff0c;传统的手写代码开发方式已经无法满足迅速推出应用程序的需求。为了加快软件开发的速度并降低技术门槛&#xff0c;低代码开发模式应运而生。 一、低代码的定义 低代码是一种软件开发方法&#xff0c;通过使用可视化编程工具和少…

webpack(三)loader

定义 loader用于对模块的源代码进行转换&#xff0c;在imporrt或加载模块时预处理文件 webpack做的事情&#xff0c;仅仅是分析出各种模块的依赖关系&#xff0c;然后形成资源列表&#xff0c;最终打包生成到指定文件中。 在webpack内部&#xff0c;任何文件都是模块&#x…

堆的 shift up(Java 实例代码)

目录 堆的 shift up Java 实例代码 src/runoob/heap/HeapShiftUp.java 文件代码&#xff1a; 堆的 shift up 本小节介绍如何向一个最大堆中添加元素&#xff0c;称为 shift up。 假设我们对下面的最大堆新加入一个元素52&#xff0c;放在数组的最后一位&#xff0c;52大于父…

蓝桥杯 2240. 买钢笔和铅笔的方案数c++解法

最近才回学校。在家学习的计划不翼而飞。但是回到学校了&#xff0c;还是没有找回状态。 现在是大三了&#xff0c;之前和同学聊天&#xff0c;说才大三无论是干什么&#xff0c;考研&#xff0c;找工作&#xff0c;考公&#xff0c;考证书 还都是来的及的。 但是心里面…

深度刨析数据在内存中的存储

✨博客主页&#xff1a;小钱编程成长记 &#x1f388;博客专栏&#xff1a;进阶C语言 深度刨析数据在内存中的存储 1.数据类型介绍1.1 类型的基本归类 2.整形在内存中的存储2.1 原码、反码、补码2.2 大小端介绍 3.浮点型在内存中的存储3.1 一个例子3.2 浮点数的存储规则3.3指数…

树和二叉树基础

引言&#xff1a; 树是一种非线性的结构&#xff0c;也是由一个一个的结点构成。 树的一些基本概念&#xff1a; 节点的度&#xff1a;一个节点含有的子树的个数称为该节点的度&#xff1b;如上图&#xff1a;A的度为6 叶节点或终端节点&#xff1a;度为0的节点称为叶节点。…

聊天机器人将取代人工客服?电商界的超级“贵人”

聊天机器人在全球范围内取得了成功&#xff0c;目前有58%的 B2B公司和42%的 B2C公司使用聊天机器人&#xff0c;而且这个数字预计还会继续增长。原因有很多&#xff0c;聊天机器人能够模拟人类交互并每天 24小时提供客户服务。当客户有疑问时&#xff0c;不用等上几小时才能得到…

【RabbitMQ】RabbitMQ 服务无法启动。系统出错。发生系统错误 1067。进程意外终止。

问题描述 RabbitMQ 服务无法启动。 rabbitmq-service.bat startRabbitMQ 服务正在启动 . RabbitMQ 服务无法启动。系统出错。发生系统错误 1067。进程意外终止。原因分析 RabbitMQ和Erlang版本不匹配。 解决方案 查询并安装RabbitMQ版本对应Erlang版本 https://www.rabbitm…

[ROS]yolov8部署ROS

Yolov8是一种基于PyTorch深度学习框架的轻量级目标检测算法&#xff0c;具有高效、准确和快速的特点&#xff0c;因此在机器人领域得到了广泛的应用。而ROS&#xff08;Robot Operating System&#xff09;是一个用于机器人软件开发的框架&#xff0c;提供了各种工具和库&#…

高级DBA带你解决达梦国产数据库数据同步至clickhouse数据库通用方法(全中国唯一一份)关键技术讲解

步骤1、安装达梦8国产数据库 参考笔者之前写的博文&#xff0c;怎么安装国产达梦8数据库&#xff0c;按博文提前装好&#xff01; https://blog.csdn.net/nasen512/article/details/126872483 步骤2、安装好clickhouse数据库 参考笔者之前写过的博文&#xff0c;将clickho…

Hadoop HDFS 高阶优化方案

目录 一、短路本地读取&#xff1a;Short Circuit Local Reads 1.1 背景 ​1.2 老版本的设计实现 ​1.3 安全性改进版设计实现 1.4 短路本地读取配置 1.4.1 libhadoop.so 1.4.2 hdfs-site.xml 1.4.3 查看 Datanode 日志 二、HDFS Block 负载平衡器&#xff1a;Balan…

python通过docker打包执行

背景 正常情况下,python脚本执行需要安装有python环境,那python环境虽然也可以通过移植的方法来安装,那总归是比较麻烦的,下面通过docker打包的方式来执行python脚本 1、安装python镜像 准备两个文件即可,dockerfile、requirements.txt两个文件的内容分别如下 同目录下…