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.mzph.cn/bicheng/22321.shtml

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

相关文章

抖店商家疑惑,自然流量突然下滑,为什么呢?

大家好&#xff0c;我是喷火龙。 很多的抖店商家会遇到一种情况&#xff0c;那就是自己店铺的流量好好的&#xff0c;不知道怎么的就突然没流量了&#xff0c;各方面的数据都断崖式的下降。 为什么会这样呢&#xff1f;原因有以下几点&#xff0c;大家可以检查一下&#xff0…

低代码和零代码软件时代质量管理(QM)和质量管理系统(QMS)

【前言】 质量控制过程的目的是为了确保产品的制造标准得到保持和改进。质量控制过程使公司能够满足客户的期望&#xff0c;同时确保产品质量的一致水平。采用这些标准创造了一种公司文化&#xff0c;鼓励所有员工努力实现高质量的生产标准。低代码和零代码软件可以成为质量控…

【网络通信层】华为云连接MQTT设备

本文介绍华为云设备连接到设备的操作。 目录 一、在华为云创建设备 二、连接MQTT 三、通信 一、在华为云创建设备 现在华为云上可以免费使用部分受限服务&#xff0c;包括免费创建自己的设备连接。 首先&#xff0c;登录华为云平台共建智能世界云底座-华为云 (huaweicl…

Qt Window Dialog 无标题栏 ,无边框,可拖动

1.效果&#xff1a; 2. 主要实现步骤&#xff1a; 设置窗口 flag&#xff1a; this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); 创建变量存储位置 QPoint m_dragPosition; 对鼠标左键按下和移动事件做处理 void DraggableDialog::mousePre…

Web 页面性能衡量指标-以用户为中心的效果指标

Web 页面性能衡量指标-以用户为中心的性能指标 以用户为中心的性能指标是理解和改进站点体验的关键点 一、以用户为中心的性能指标 1. 指标是用来干啥的&#xff1f; 指标是用来衡量性能和用户体验的 2. 指标类型 感知加载速度&#xff1a;网页可以多快地加载网页中的所有…

如何在vs code中安装JavaFX

目录 下载JavaFX 配置vs code工程 编写测试代码 下载JavaFX 网站链接:https://openjfx.io 选择如下的版本

从1.0到4.0,看看你公司的费控模式是第几代?

早在2021年9月&#xff0c;艾媒咨询在《2021H1企业费控报销服务专题研究报告》中&#xff0c;第一次对企业费用管控模式的进化历程进行了清晰的划代&#xff1a;1.0手工模式、2.0网报模式、3.0移动报销模式、4.0智能费控模式。 2022年&#xff0c;在《中国企业费用管理发展白皮…

vr样板房实景漫游展示制作解决了地产商难题

家具和软装销售中&#xff0c;如何直观展示产品优势一直是老板们的难题。口头描述往往难以让客户真正感受到产品的独特之处&#xff0c;这不仅影响了销售效果&#xff0c;也增加了沟通的难度。但现在&#xff0c;我们有了全新的解决方案——样板房VR全景编辑软件! 样板房VR全景…

精打细算:可燃气体报警器检验收费的合理规划与管理

随着工业化的快速发展&#xff0c;可燃气体报警器已经成为各类工业场所不可或缺的安全设备。 它的主要功能是在可燃气体浓度超标时发出警报&#xff0c;有效预防和减少火灾、爆炸等安全事故的发生。 然而&#xff0c;为了确保报警器能够持续、准确地发挥作用&#xff0c;定期…

科技盛事即将拉开帷幕,WWDC2024官宣定档,亮点抢先看!

随着全球科技爱好者们对苹果年度开发者大会&#xff08;WWDC&#xff09;的期待日益高涨&#xff0c;今年的WWDC24&#xff08;苹果全球开发者大会&#xff09;&#xff0c;正式宣告这一科技盛事将于北京时间6月11日凌晨1点拉开帷幕。距离WWDC 2024的召开只剩下一周时间&#x…

【电子取证篇】电子数据取证标准合集更新202405(附下载)

【电子取证篇】电子数据取证标准合集更新202405&#xff08;附下载&#xff09; 电子数据取证相关标准合集&#xff0c;按照司法鉴定职业分类目录&#xff0c;对电子数据鉴定可能涉及的测试、测量方法进行标准归类&#xff0c;更新于2024年05月14日—【蘇小沐】 &#xff08;…

前端localForage存储数据使用教程

前言 前端本地化存储算是一个老生常谈的话题了&#xff0c;我们对于 cookies、Web Storage&#xff08;sessionStorage、localStorage&#xff09;的使用已经非常熟悉&#xff0c;在面试与实际操作之中也会经常遇到相关的问题&#xff0c;但这些本地化存储的方式还存在一些缺陷…

期权懂题库免费!期权开户测试难吗?多少分算合格通过?

今天带你了解期权懂题库免费&#xff01;期权开户测试难吗&#xff1f;多少分算合格通过&#xff1f;期权开户测试通常要求投资者达到一定的合格分数&#xff0c;以确保他们具备足够的理解和知识来参与期权交易。 期权开户测试难吗&#xff1f; 期权开户测试的难度因人而异&am…

【设计模式深度剖析】【1】【行为型】【模板方法模式】| 以烹饪过程为例加深理解

&#x1f448;️上一篇:结构型设计模式对比 文章目录 模板方法模式定义英文原话直译如何理解呢&#xff1f; 2个角色类图代码示例 应用优点缺点使用场景 示例解析&#xff1a;以烹饪过程为例类图代码示例 模板方法模式 模板方法模式&#xff08;Template Method Pattern&…

LED驱动IC:HC2161,升压型LED恒流驱动ic,供应LED灯杯单节电池以上供电的LED灯串平板显示LED背光大功率LED照明

LED驱动IC&#xff1a; HC2161:升压型LED恒流驱动ic 概述&#xff1a;HC2161是一款高效率、高精度的升 压型大功率LED恒流驱动控制芯片。 HC2161内置高精度误差放大器&#xff0c;固 定关断时间控制电路&#xff0c;恒流驱动电路等&#xff0c; 特别适合大功率、多个高亮…

Kaggle平台进行Python版本降级

前言 最近在复现语音合成模型VITS&#xff0c;由于目前没有算力故去Kaggle白嫖运算资源。 VITS的运行环境要求如下 Cython0.29.21 librosa0.8.0 matplotlib3.3.1 numpy1.18.5 phonemizer2.2.1 scipy1.5.2 tensorboard2.3.0 torch1.6.0 torchvision0.7.0 Unidecode1.1.1截至2…

视频号小店,常见的违规条例!98%的商家必犯的违规细节!

哈喽~我是电商月月 做电商&#xff0c;不管哪个平台都有属于自己的规则条例&#xff0c;这些违规细节&#xff0c;一定要提前了解 所以今天&#xff0c;月月就给大家分享一下&#xff0c;做视频号小店的话&#xff0c;有哪些常见的违规细节 这里我们分三点讲解 一&#xff…

【分享】两种方法禁止修改Word文档

对于比较重要的Word文件&#xff0c;不想被随意编辑修改&#xff0c;可以试试以下两个方法&#xff0c;不清楚的小伙伴&#xff0c;一起来看看吧&#xff01; 方法1&#xff1a;设置“只读方式” 我们可以给Word文档设置以“只读方式”打开&#xff0c;这样就算编辑修改了文档…

6月软考新通知:24下集成大概率是中级蕞简单的一门

2024下半年软考6月新通知&#xff1a; 一、24下软考考试时间安排&#xff1a; 24下半年软考报名时间&#xff1a;8月19日-9月15日 24下半年软考考试时间&#xff1a;11月9-12日 24下半年软考成绩查询&#xff1a;12月中&#xff08;预计&#xff09; 二、考情分析 24上软考…

09_JavaWeb会话

1.会话 HTTP是一种无状态协议&#xff1b; HTTP协议对于发送过请求或者响应都不做持久化处理具体来说就是客户端发送请求&#xff0c;服务器接收请求&#xff0c;但是服务器自身不会记录每一条请求都是由哪一个客户端发出的&#xff1b; 会话管理是通过Cookie和Session配合解…