vue2拖拉拽做个模拟公式工具

news2025/4/8 5:22:55

1. 成图

在这里插入图片描述

2. 介绍

就是简单拖拉拽来做个规则运算器,具体运算规则、校验规则自己加。

3. 代码

HTML代码

<template>

    <div class="red-cont">
      <div class="red-top">
        <div
          class="red-top-left"
        >
          <div class="red-showarea">
            <div class="red-showarea-title">公式展示</div>
            <div class="red-showarea-list">
              <span
                v-for="(item, index) in valueList"
                :key="index"
              >{{ item.label }}</span>
            </div>
          </div>
          <div class="red-ctrlarea  user-no-select">
            <div class="red-ctrlarea-title">公式编辑</div>
            <div
              class="red-ctrlarea-list"
              @drop="handleDrop"
              @dragleave="handleDragLeave($event)"
              @dragover.stop.prevent="handleDragOver($event)"
            >
              <div v-if="valueList.length === 0" class="red-ctrlarea-hint">
                请拖曳字段、数字或操作符到编辑区域
              </div>
              <div
                v-for="(item, index) in valueList"
                :key="item.id"
                :class="[
                  'red-ctrl-item',
                  index === draggingOverIndex - 1 ? 'red-ctrl-inject-before' : '',
                  index === draggingOverIndex ? 'red-ctrl-inject-after' : ''
                ]"
                @drop.stop.prevent="handleDrop"
                @dragover.stop.prevent="handleDragOver($event, index)"
              >
                <div
                  class="red-ctrl-item-cont"
                  draggable="true"
                  @dragstart="handleDragStart($event, item, item.type)"
                >
                  <div :alt="item.label">{{ item.label }}</div>
                  <i
                    class="el-icon-circle-close red-ctrl-item-close"
                    @click="removeValueItem(item, index)"
                  />
                </div>

              </div>
            </div>
          </div>
        </div>
        <div class="red-top-right user-no-select">
          <div class="red-paramtype">
            <el-select v-model="paramType">
              <el-option
                v-for="item in paramTypeOptions"
                :key="item.value"
                :label="item.label"
                :disabled="item.disabled"
                :value="item.value"
              />
            </el-select>
          </div>
          <div class="red-paramoptions">
            <div
              v-for="(item, index) in paramOptions"
              :key="index"
              class="red-paramoptions-item"
              draggable="true"
              @dragstart="handleDragStart($event, item, paramType)"
            >
              {{ item.label }}
            </div>
          </div>
        </div>
      </div>
      <div class="red-bottom user-no-select">
        <div class="red-bottom-left">
          <div
            v-for="(item, index) in sourceList"
            :key="index"
            class="red-source-item"
            draggable="true"
            @dragstart="handleDragStart($event, item, 'ctrl')"
          >
            {{ item.label }}
          </div>
        </div>
        <div
          class="red-clear"
          @click="clearValueList"
        ><br></div>
      </div>
    </div>
</template>

VUE2的代码

export default {
  components: {},
  props: {},
  data() {
    return {
      paramType: 'field',
      paramTypeOptions: [
        { value: 'field', label: '字段' },
        { value: 'attribute', label: '机组属性', disabled: true }
      ],

      paramOptions: [
        { value: Math.random(), label: '字段1' },
        { value: Math.random(), label: '字段2' },
        { value: Math.random(), label: '字段3' },
        { value: Math.random(), label: '字段4' },
        { value: Math.random(), label: '字段5' }
      ],

      valueList: [],

      sourceList: [
        { label: '1', value: '1' },
        { label: '2', value: '2' },
        { label: '3', value: '3' },
        { label: '4', value: '4' },
        { label: '5', value: '5' },
        { label: '6', value: '6' },
        { label: '7', value: '7' },
        { label: '8', value: '8' },
        { label: '9', value: '9' },
        { label: '0', value: '0' },
        { label: '00', value: '00' },
        { label: '(', value: '(' },
        { label: ')', value: ')' },
        { label: '.', value: '.' },
        { label: '+', value: '+' },
        { label: '-', value: '-' },
        { label: '*', value: '*' },
        { label: '/', value: '/' },
        { label: '>', value: '>' },
        { label: '<', value: '<' },
        { label: '==', value: '==' },
        { label: '>=', value: '>=' },
        { label: '<=', value: '<=' },
        { label: '!', value: '!' },
        { label: '||', value: '||' },
        { label: '&&', value: '&&' }
      ],

      draggingIndex: null,
      draggingOverIndex: null
    };
  },
  created() {},
  methods: {
    clearValueList() {
      this.valueList.splice(0, this.valueList.length);
    },

    handleDragLeave(e) {
      console.log('tree drag leave: ', e);
      this.draggingOverIndex = null;
    },

    handleDrop(e) {
      const data = JSON.parse(e.dataTransfer.getData('text/plain'));

      const { valueList, draggingOverIndex } = this;
      const item = Object.assign({}, data, {
        id: Math.random().toString(36).substr(2, 9)
      });

      if (typeof draggingOverIndex === 'number') {
        valueList.splice(draggingOverIndex, 0, item);

        const dataIndex = valueList.findIndex(item => item.id === data.id);

        if (dataIndex !== -1) {
          valueList.splice(dataIndex, 1);
        } else {
          //
        }
      } else {
        const dataIndex = valueList.findIndex(item => item.id === data.id);

        if (dataIndex !== -1) {
          valueList.splice(dataIndex, 1);
        } else {
          //
        }

        valueList.push(item);
      }

      this.draggingOverIndex = null;
    },

    handleDragOver(e, targetIndex) {
      console.log('handleDragOver', e, targetIndex);

      this.draggingOverIndex = targetIndex;
    },

    handleDragStart(e, item, type) {
      e.dataTransfer.setData('text/plain', JSON.stringify(Object.assign({
        type: type
      }, item)));
    },

    removeValueItem(item, index) {
      this.valueList.splice(index, 1);
    }
  }
};

less/scss代码

.red-cont{
    display: flex;
    height: 100%;
    overflow: hidden;
    flex-direction: column;
}
.red-top{
    flex: 1;
    overflow: hidden;
    display: flex;
    align-items: stretch;
    justify-content: space-between;
}
.red-top-left{
    flex: 1;
    overflow: hidden;
}
.red-showarea{
    display: flex;
    flex-direction: column;
    height: 35%;
}
.red-showarea-title{
    flex-shrink: 0;
}
.red-showarea-list{
    flex: 1;
    overflow: auto;
    padding: 10px;
}
.red-ctrlarea{
    display: flex;
    flex-direction: column;
    height: 65%;
}
.red-ctrlarea-title{
    flex-shrink: 0;
}
.red-ctrlarea-hint{
    padding: 10px;
    color: #ccc;
}
.red-ctrlarea-list{
    flex: 1;
    overflow-x: hidden;
    overflow-y: auto;
    border: 1px dashed #ccc;

    display: flex;
    flex-wrap: wrap;
    align-content: flex-start;
}
.red-ctrl-item{
    padding-left: 10px;
    padding-top: 10px;
    max-width: 200px;
}
.red-ctrl-inject-before{
    &>.red-ctrl-item-cont{
        border-right: 1px dashed #ccc;
    }
}
.red-ctrl-inject-after{
    &>.red-ctrl-item-cont{
        border-left: 1px dashed #ccc;
    }
}
.red-ctrl-item-cont{
    padding: 5px;
    position: relative;
    cursor: grab;
    border: 1px solid transparent;

    &>div{
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
}
.red-ctrl-item-close{
    position: absolute;
    top: -5px;
    right: -5px;
    cursor: pointer;
}
.red-paramtype{
    flex-shrink: 0;
    padding: 10px;
    .el-select{
        width: 100%;
    }
}
.red-paramoptions{
    flex: 1;
    padding: 10px;
    overflow: auto;
}
.red-paramoptions-item{
    padding: 5px;
    cursor: grab;
    &:hover{
        background-color: #ccc;
    }
}
.red-bottom{
    flex-shrink: 0;
    height: 200px;
    display: flex;
    align-items: center;

}
.red-bottom-left{
    flex: 1;
    display: flex;
    flex-wrap: wrap;
    padding: 1px;
}
.red-clear{
    padding: 10px;
    border: 1px solid #fff;
    cursor: grab;
}
.red-source-item{
    width: 50px;
    height: 50px;
    line-height: 50px;
    text-align: center;
    margin: 5px;
    background-color: #ccc;
    cursor: grab;
}

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

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

相关文章

Windows查重工具,强烈推荐大家收藏!

我大家在用电脑的时候&#xff0c;是不是发现用得越久&#xff0c;电脑里的软件和文件就越多&#xff1f; 今天我给大家带来的这两款重复文件查找神器&#xff0c;简直就是电脑里的“清洁小能手”&#xff0c;能帮你把那些重复的文件和文件夹找出来。 Easy DupLicate Finder 重…

使用python完成手写数字识别

入门图像识别的第一个案例,看到好多小伙伴分享,也把自己当初的思路捋捋,写成一篇博客,作为记录和分享,也欢迎各位交流讨论。 实现思路 数据集:MNIST(包含60,000个训练样本和10,000个测试样本) 深度学习框架:Keras(基于TensorFlow) 模型架构:卷积神经网络(CNN) 实…

OpenLayers:如何控制Overlay的层级?

我最近在使用Overlay的时候遇到了一个问题&#xff0c;我向地图中添加了两种不同的Overlay&#xff08;下图中的蓝色标牌和粉色标牌&#xff09;&#xff0c;我希望粉色标牌可以显示在最上层&#xff0c;可偏偏蓝色标牌却将其遮挡住了。于是我对Overlay的层级开始起了兴趣&…

《Golang高性能网络编程:构建低延迟服务器应用》

在本文中&#xff0c;我们将深入探讨Golang高性能网络编程&#xff0c;帮助您构建低延迟服务器应用。我们将介绍Golang的网络编程特性、优化技巧和实际案例&#xff0c;让您更好地理解和应用Golang在网络编程领域的优势。 高性能网络编程简介 什么是Golang高性能网络编程 高性能…

数据结构C语言练习(设计循环队列)

一、循环队列简介 循环队列是一种线性数据结构&#xff0c;基于 FIFO&#xff08;先进先出&#xff09;原则&#xff0c;将队尾连接到队首形成循环。其核心优势是能复用队列之前用过的空间&#xff0c;避免普通队列 “假溢出” 问题。实现时&#xff0c;通常申请 k1 大小的数组…

vscode代码片段的设置与使用

在 Visual Studio Code (VS Code) 中&#xff0c;可以通过自定义**代码片段&#xff08;Snippets&#xff09;**快速插入常用代码模板。以下是详细设置步骤&#xff1a; 步骤 1&#xff1a;打开代码片段设置 按下快捷键 Ctrl Shift P&#xff08;Windows/Linux&#xff09;或…

uniapp -- 列表垂直方向拖拽drag组件

背景 需要在小程序中实现拖拽排序功能,所以就用到了m-drag拖拽组件,在开发的过程中,发现该组件在特殊的场景下会有些问题,并对其进行了拓展。 效果 组件代码 <template><!-- 创建一个垂直滚动视图,类名为m-drag --><scroll

一款非常小的软件,操作起来非常丝滑!

今天我想给大家分享一款超级实用的小软件&#xff0c;它是一款电脑上用的倒计时和关机助手。 关机助手 帮你自动关机 这款关机助手特别小巧&#xff0c;完全不需要安装&#xff0c;文件大小才60KB&#xff0c;比一个小小的文件还小。你只需要把它下载下来&#xff0c;双击打开…

FrameWork基础案例解析(四)

文章目录 单独拉取framework开机与开机动画横屏Android.mk语法单独编译SDKmake 忽略warning单独修改和编译Camera2单独编译Launcher3Android Studio 导入、修改、编译Settings导入 Android Studio 导入、修改、编译Launcher3android 开机默认进入指定Launcher植入自己的apk到系…

通过 C# 提取PDF文档中的图片

当 PDF 文件中包含有价值的图片&#xff0c;如艺术画作、设计素材、报告图表等&#xff0c;提取图片可以将这些图像资源进行单独保存&#xff0c;方便后续在不同的项目中使用&#xff0c;避免每次都要从 PDF 中查找。本文将介绍如何使用C#通过代码从PDF文档中提取图片&#xff…

国标GB28181视频监控平台EasyCVR保驾护航休闲娱乐“九小场所”安全运营

凭借降低人力资源、节约物资成本的优势&#xff0c;在多个场景得到广泛应用。如今&#xff0c;棋牌室、洗浴中心、酒店这类人员频繁流动和密集的场所&#xff0c;已成为安全管理的重点。​ 尽管部分棋牌室已安装了监控设备&#xff0c;但是设备功能单一&#xff0c;只能实现一…

GoLand 2024.3 中文 GO语言开发工具

GoLand 2024.3 中文 GO语言开发工具 文章目录 GoLand 2024.3 中文 GO语言开发工具一、介绍二、效果三、下载 一、介绍 JetBrains GoLand 2024 &#xff0c;是一款GO语言开发工具&#xff0c;全行代码补全&#xff1a;能使用本地运行的上下文感知深度学习模型&#xff0c;可以自…

CentOS 7 强制升级Docker 24.x终极指南(解决MySQL8镜像兼容性问题)

CentOS 7 强制升级Docker 24.x终极指南&#xff08;解决MySQL8镜像兼容性问题&#xff09; 旧版本&#xff1a; 新版本docker&#xff1a; 一、问题背景与方案选型 1.1 典型报错分析 The designated data directory /var/lib/mysql/ is unusable根本原因&#xff1a;旧版…

【区块链安全 | 第十九篇】类型之映射类型

文章目录 映射类型可迭代映射 映射类型 映射类型使用语法 mapping(KeyType KeyName? > ValueType ValueName?)&#xff0c;映射类型的变量声明使用语法 mapping(KeyType KeyName? > ValueType ValueName?) VariableName。 KeyType 可以是任何内置值类型、bytes、st…

Flask与 FastAPI 对比:哪个更适合你的 Web 开发?

在开发 Web 应用时&#xff0c;Python 中有许多流行的 Web 框架可以选择&#xff0c;其中 Flask 和 FastAPI 是两款广受欢迎的框架。它们各有特色&#xff0c;适用于不同的应用场景。本文将从多个角度对比这两个框架&#xff0c;帮助你更好地选择适合的框架来构建你的 Web 应用…

QT 中的元对象系统(五):QMetaObject::invokeMethod的使用和实现原理

目录 1.简介 2.原理概述 3.实现分析 3.1.通过方法名调用方法的实现分析 3.2.通过可调用对象调用方法的实现分析 4.使用场景 5.总结 1.简介 QMetaObject::invokeMethod 是 Qt 框架中的一个静态方法&#xff0c;用于在运行时调用对象的成员函数。这个方法提供了一种动态调…

【无人机】无人机PX4飞控系统高级软件架构

目录 1、概述&#xff08;图解&#xff09; 一、数据存储层&#xff08;Storage&#xff09; 二、外部通信层&#xff08;External Connectivity&#xff09; 三、核心通信枢纽&#xff08;Message Bus&#xff09; 四、硬件驱动层&#xff08;Drivers&#xff09; 五、飞…

【SPP】蓝牙链路控制(LC)在SPP中互操作性深度解析

在蓝牙协议栈的精密分层体系中&#xff0c;其链路控制&#xff08;Link Control, LC&#xff09;层作为基带层的核心组件&#xff0c;承载着物理信道管理、连接建立与维护等关键任务。其互操作性要求直接决定了不同厂商设备能否实现无缝通信。本文将以蓝牙技术规范中的LC互操作…

算法每日一练 (25)

&#x1f4a2;欢迎来到张翊尘的技术站 &#x1f4a5;技术如江河&#xff0c;汇聚众志成。代码似星辰&#xff0c;照亮行征程。开源精神长&#xff0c;传承永不忘。携手共前行&#xff0c;未来更辉煌&#x1f4a5; 文章目录 算法每日一练 (25)四数之和题目描述解题思路解题代码c…

【大模型基础_毛玉仁】6.4 生成增强

目录 6.4 生成增强6.4.1 何时增强1&#xff09;外部观测法2&#xff09;内部观测法 6.4.2 何处增强6.4.3 多次增强6.4.4 降本增效1&#xff09;去除冗余文本2&#xff09;复用计算结果 6.4 生成增强 检索器得到相关信息后&#xff0c;将其传递给大语言模型以期增强模型的生成能…