CodeMirror 创建标签计算编辑器

         在日常开发中对于一些数据计算场景可能会遇到标签计算的需求,下面关于如何使用CodeMirror实现标签计算编辑功能。

1,结果图

2,主体代码逻辑

大家只需要复制粘贴主要codeMirror使用逻辑即可


<template><el-dialogref="dialogRef":model-value="visible"width="800px":close-on-press-escape="false"destroy-on-closeappend-to-body@close="() => {$emit('update:visible', false);}"><template #title><span> 编辑表达式 </span></template><!-- 左侧无用dom元素已删除 --><div class="content__right"><div class="symbol-group"><div v-for="item in symbolList" :key="item.code" class="symbol-item" @click="handleSymbolClick(item)">{{ item.name }}</div></div><!-- 代码编辑器 --><textarearef="codeEditorContainerRef"v-model="currentCodeInEditor"class="editor"/></div></div><template #footer><div class="dialog-button-box"><el-buttonsize="small"@click="() => {$emit('update:visible', false);}">取消</el-button><el-button size="small" type="primary" @click="handleOk">确定</el-button></div></template></el-dialog>
</template><script lang="ts">
import { defineComponent, reactive, toRefs, watch, ref, onMounted, nextTick } from 'vue';
import { InfoFilled, Search } from '@element-plus/icons';
import { TreeNodeData } from 'element-plus/es/el-tree/src/tree.type.d';
// 引入代码编辑器核心配置包
import * as CodeMirror from 'codemirror';
import 'codemirror/lib/codemirror.css';// 引入代码编辑器主题样式
import 'codemirror/theme/base16-light.css';
import 'codemirror/theme/ambiance.css';
import 'codemirror/addon/hint/show-hint.css';
import 'codemirror/theme/monokai.css';
import 'codemirror/theme/material.css';
import 'codemirror/theme/dracula.css';
import 'codemirror/addon/fold/foldgutter.css';
import 'codemirror/mode/javascript/javascript';// 引入代码编辑器常用语言包
require('codemirror/addon/edit/matchbrackets');
require('codemirror/addon/selection/active-line');
require('codemirror/mode/sql/sql');
require('codemirror/addon/hint/show-hint');
require('codemirror/addon/hint/sql-hint');
require('codemirror/keymap/sublime');// 引入代码折叠文件
require('codemirror/addon/fold/foldcode');
require('codemirror/addon/fold/foldgutter');
require('codemirror/addon/fold/brace-fold');
require('codemirror/addon/fold/xml-fold');
require('codemirror/addon/fold/indent-fold');
require('codemirror/addon/fold/markdown-fold');
require('codemirror/addon/fold/comment-fold');export default defineComponent({name: 'RemarksDialog',components: {},props: {visible: {type: Boolean,default: false,},data: {type: String,default: '',},},emits: ['update:visible', 'save'],setup(props, { emit }) {const dialogRef = ref();const state = reactive({// 符号列表symbolList: [{id: 'plus',code: 'plus',name: '+',type: 'operator',},{id: 'minus',code: 'minus',name: '-',type: 'operator',},{id: 'multiply',code: 'multiply',name: '*',type: 'operator',},{id: 'exception',code: 'exception',name: '/',type: 'operator',},{id: 'leftBrackets',code: 'leftBrackets',name: '(',type: 'operator',},{id: 'rightBrackets',code: 'rightBrackets',name: ')',type: 'operator',},] as SymbolItem[],});// 代码编辑器容器实例const codeEditorContainerRef = ref<HTMLElement | null>();// 代码编辑器let editor : TreeNodeData | null;// 编辑器当前所用编程语言const currentLanguage = ref('javascript');// 编辑器当前主题const currentTheme = ref('base16-light');// 编辑器当前展示的代码const currentCodeInEditor = ref();// 获取表达式的元素集合const getCalcResult = (): SymbolItem[] => {const temp: any[] = editor?.getValue().split('$');// 清除最后一个空格元素temp.pop();// 循环生成最后的集合return temp.map((item: string) => state.calculationIdMap[item]).filter((item) => !!item);};/*** @description: 创建标签* @return {*}*/const makeLabel = (mark: any) => {const spanDom = document.createElement('span');const label = mark.variable;spanDom.title = label;spanDom.innerText = label;spanDom.classList.add('textarea-tag');spanDom.dataset.variable = mark.variable;editor?.markText(mark.start, mark.end, {replacedWith: spanDom, // 将特定位置的文本替换成给定的节点元素,必须是行元素,不能是块元素atomic: true, // 原子化,会把节点元素当成一个整体,光标不会进入其中});};/*** @description: 插入标签* @return {*}*/const insertLabel = (content: any, isCalcDim: boolean) => {if (!content) return;const cursor = editor?.getCursor();editor?.replaceSelection(`${content.code}$`);makeLabel({start: cursor,end: editor?.getCursor(), // 获取自定义标签插入之后的光标对象variable: content.name,});editor?.setCursor(editor?.getCursor());editor?.focus();};/*** 初始化代码编辑器*/const initEditor = () => {nextTick(() => {if (codeEditorContainerRef.value) {editor = CodeMirror.fromTextArea(codeEditorContainerRef.value, {// 编辑器语言的模式mode: currentLanguage.value,// 编辑器主题风格theme: currentTheme.value,// 缩进的时候,是否把前面的 N*tab 大小的空间,转化为 N个tab 字符indentWithTabs: true,// 是否使用 mode 提供的上下文的缩进smartIndent: true,// 编辑器左侧是否显示行号lineNumbers: true,// 括号匹配matchBrackets: true,// 初始化时是否自动获得焦点autofocus: true,// 代码自动换行lineWrapping: true,// 代码块折叠foldGutter: true,// 只读readOnly: false,// 代码块折叠样式gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'],// 自定义快捷键extraKeys: { Ctrl: 'autocomplete' },// 自定义提示选项hintOptions: {tables: {users: ['name', 'score', 'birthDate'],countries: ['name', 'population', 'size'],},},});// 公式回显if (props.data) {const dataArray = JSON.parse(props.data);dataArray.forEach((item: any) => {insertLabel(item, false);state.calculationIdMap[item.code] = item;});// 重新计算时间维度和可用维度setTimeout(() => {// 重新计算时间维度和其他可用维度resetCurrentDateDimension();resetCurrentOtherDimension();}, 500);}}});};/*** @description: 符号点击触发方法* @param {SymbolItem} data* @return {*}*/const handleSymbolClick = (data: SymbolItem) => {insertLabel(data, false);state.calculationIdMap[data.code] = data;};watch(() => props.visible,async (newVal) => {if (newVal) {initEditor();await getIndicatorList();} else {state.currentOtherDimension = [];state.currentDateDimension = {} as any;}},);return {...toRefs(state),dialogRef,Search,codeEditorContainerRef,currentCodeInEditor,handleSymbolClick,};},
});
</script><style lang="scss" scoped></style>

大家只需要关注codeMirror插件的引入以及相关api 的使用即可。

未解决的问题:在点击生成标签只有,不能通过鼠标点击直接移动光标位置,只能通过方向键移动光标位置。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python——网络编程

流程图 面向连接的套接字 面向连接的通信提供序列化的、可靠的和不重复的数据交付&#xff0c;而没有记录边界。主要的协议是传输控制协议&#xff08;TCP&#xff09;; TCP套接字&#xff0c;在python中&#xff0c;必须使用SOCK_STREAM作为套接字类型 tcp的特点 面向连接…

AI大模型应用开发实践:5.快速入门 Assistants API

快速入门 Assistants API Assistants API 允许您在自己的应用程序中构建人工智能助手。一个助手有其指令,并可以利用模型、工具和知识来回应用户查询。 Assistants API 目前支持三种类型的工具: 代码解释器 Code Interpreter检索 Retrieval函数调用 Function calling使用 P…

数据结构学习笔记

参考教材&#xff1a;数据结构C语言版&#xff08;严蔚敏&#xff0c;杨伟民编著&#xff09; 参考课程&#xff1a;青岛大学王卓老师&#xff1a;数据结构与算法基础 思维导图&#xff1a;XMind、幕布 正在备考&#xff0c;结合自身空闲时间&#xff0c;不定时更新&a…

Three.js的阴影技术,创建逼真效果的必备!

three.js是一个流行的用于创建和展示3D图形的JavaScript库&#xff0c;它提供了多种阴影技术来增强3D场景的真实感和视觉效果。 一、常用阴影技术 1. 基于光线的阴影&#xff08;Raytraced Shadows&#xff09;&#xff1a;通过跟踪光线的路径来计算阴影&#xff0c;产生非常…

大数据之CDH对Hdfs做Balance数据均衡/数据平衡/数据倾斜

问题的来源: 由于在hive工具运行sql,出现sql卡顿的情况,去cdh上查看yarn资源的分布情况,发现了整个cdh平台中hdfs和yarn资源分布不均匀,大量的爆红显示: 以下 DataNode 数据目录 位于小于其可用空间 10.0 吉字节 的文件系统中。 /data1/dfs/dn&#xff08;可用&#xff1a;7.2 …

Python爬虫协程批量下载图片

import aiofiles import aiohttp import asyncio import requests from lxml import etree from aiohttp import TCPConnectorclass Spider:def __init__(self, value):# 起始urlself.start_url value# 下载单个图片staticmethodasync def download_one(url):name url[0].spl…

SpringCloud 微服务中网关如何记录请求响应日志?

在基于SpringCloud开发的微服务中&#xff0c;我们一般会选择在网关层记录请求和响应日志&#xff0c;并将其收集到ELK中用作查询和分析。 今天我们就来看看如何实现此功能。 日志实体类 首先我们在网关中定义一个日志实体&#xff0c;用于组装日志对象 Data public class …

第九十七节 Java面向对象设计 - Java Object.Finalize方法

Java面向对象设计 - Java Object.Finalize方法 Java提供了一种在对象即将被销毁时执行资源释放的方法。 在Java中&#xff0c;我们创建对象&#xff0c;但是我们不能销毁对象。 JVM运行一个称为垃圾收集器的低优先级特殊任务来销毁不再引用的所有对象。 垃圾回收器给我们一个…

函数计数和跟踪 --- console的count和trace方法

新学到一个小方法&#xff0c;分享一下哦。 使用 console 对象的 trace ⽅法在控制台上输出当前的调用栈&#xff0c;可以追踪⼀个函数的执⾏过程。 当我们想要了解一个函数是如何被其他函数调用的&#xff0c;或者想要查看调用栈中的其他信息时&#xff0c;这个方法非常有用…

Cadence Virtuoso IC617 系统内存清理

1、清空simelation和垃圾箱下的文件 2、在虚拟机磁盘路径下&#xff0c;例如/home下面输入 cat /dev/zero > zero.fill;sync;sleep 1;sync;rm -f zero.fill 3、在windows下winR ->cmd 找到VMware安装目录和系统存放目录 Microsoft Windows [版本 10.0.19045.4412] (c…

/etc/fstab、/etc/mtab 文件详解及永久挂载(文件系统、ISO镜像、文件网络共享)

/etc/mtab /etc/mtab 是当前的分区挂载情况&#xff0c;记录的是当前系统已挂载的分区。每次挂载/卸载分区时会更新 /etc/mtab 文件中的信息&#xff08;执行 mount 命令会改变 /etc/mtab 的信息&#xff09;。 文件样例 /etc/fstab 系统开机时会主动读取 /etc/fstab 这个文…

网络服务ftp实验

网络服务之ftp vsftpd的安装和配置 rpm -qc vsftpd #检查vsftpd安装包是否存在&#xff0c;存在即不需要安装 yum install -y vsftpd #yum 安装vsftpdcd /etc/vsftpd ls #切换到安装好vsftpd目录下查看文件cp vsftpd.conf vsftpd.conf.bak.20240604 #将vsftpd的…

数据库开发-Mysql03

目录 1. 多表查询 1.1 概述 1.1.1 数据准备 1.1.2 介绍 1.1.3 分类 1.2 内连接 1.3 外连接 1.4 子查询 1.4.1 介绍 1.4.2 标量子查询 1.4.3 列子查询 1.4.4 行子查询 1.4.5 表子查询 1.5 案例 2. 事务 2.1 介绍 2.2 操作 2.3 四大特性 3. 索引 3.1 介绍 3…

算法人生(18):从神经网络的“剪枝策略”看“怎么找回时间”

IT人的工作和生活难平衡这事&#xff0c;到底要怎么解决呢&#xff0c;让我们从神经网络的“剪枝策略”中找点灵感吧&#xff01; 剪枝策略是指训练和优化深度神经网络时采取的一种技术&#xff0c;从名字就知道&#xff0c;它就像修剪树木一样&#xff0c;去除不必要的枝叶&a…

《平渊》· 捌 —— 「庄子」山木篇中的 “空船效应”

《平渊》 捌 "若能虚己以游世&#xff0c;其孰能害之&#xff1f;" "方舟而济于河&#xff0c;有虚船来触舟&#xff0c;虽有惼心之人而不怒&#xff1b;有一人子其上&#xff0c;则呼张歙之&#xff1b;一呼而不闻&#xff0c;再呼而不闻&#xff0c;于是三呼邪…

Linux C语言学习:数据类型

一、 为什么要引入数据类型 • 计算机中每个字节都有一个地址&#xff08;类似门牌号&#xff09; • CPU通过 地址 来访问这个字节的空间 0x20001103 1 0 0 1 0 0 1 1 0x20001102 1 1 1 0 1 1 1 0 0x20001101 1 1 1 1 0 1 0 1 0x20001100 0 …

STM32 MDK Keil5软件调试功能使用(无需连接硬件)

MDK Keil5 在线仿真STM32&#xff08;无需连接硬件&#xff09; 首先点击工具栏的魔术棒配置一下&#xff1a;&#xff08;记得选择自己的STM32芯片类型&#xff09; 开启调试 使用逻辑分析仪查看IO输出 会打开这个界面&#xff0c;点击左边的setup按钮 会打开这个窗口&am…

Golang | Leetcode Golang题解之第119题杨辉三角II

题目&#xff1a; 题解&#xff1a; func getRow(rowIndex int) []int {row : make([]int, rowIndex1)row[0] 1for i : 1; i < rowIndex; i {row[i] row[i-1] * (rowIndex - i 1) / i}return row }

npm install pubsub-js报错的解决汇总

我在练习谷粒商城P83时&#xff0c;选择分类时触发向后端请求选择分类catId绑定的品牌数据&#xff0c;发现前端控制台报错&#xff1a; "PubSub is not definded",找不到pubsub。 因为缺少pubsub包&#xff0c;所以开始安装此包。 于是在网上一顿搜索猛如虎&…

理解NSCopying协议

NSCopying 协议用于让对象能够被复制。实现这个协议的类需要定义如何创建该对象的副本。这个副本是独立的&#xff0c;不会与原对象共享内存地址。 为什么需要 NSCopying 协议&#xff1f; 当你需要复制对象时&#xff0c;例如将对象存储到一个集合&#xff08;如数组、字典&…