zhangrui.i
zhangrui.i
发布于 2024-09-29 / 7 阅读
0
0

前端实现Aviator表达式编辑

前端实现Aviator表达式编辑

显示效果

微信图片_20240929105702-vxxv.png

详细代码

<template>
  <div class="formula-editor">
    <div class="toolbar">
      <div class="row">
        常用变量
        <button v-for="variable in variables" :key="variable.key" @click="appendText(variable, 0)">
          {{ variable.desc }}
        </button>
      </div>

      <div class="row">
        运算符
        <button v-for="operator in operators" :key="operator.key" @click="appendText(operator, 1)">
          {{ operator.desc }}
        </button>
      </div>

      <div class="row">
        逻辑运算符
        <button v-for="logically in logicoperators" :key="logically.key" @click="appendText(logically, 1)">
          {{ logically.desc }}
        </button>
      </div>

      <div class="row">
        关联
        <button v-for="relation in relations" :key="relation.key" @click="appendText(relation, 0)">
          {{ relation.desc }}
        </button>
      </div>

      <div class="row">
        数字输入
        <input type="number" v-model="numberInput" placeholder="输入数字" style="height: 25px;margin-right: 10px;" />
        <button @click="appendNumber">插入数字</button>
      </div>

      <div class="row">
        <button @click="reset">重置</button>
      </div>
    </div>

    <draggable tag="div" class="editor" v-model="dynamicElements" @end="updateFormula">
      <div v-for="(element, index) in dynamicElements" :key="index" class="dynamic-span">
        {{ element.desc }}
        <span class="delete-btn" @click="deleteElement(index)">✖</span>
      </div>
    </draggable>

    <div class="result">
      <p>公式: {{ formula }}</p>
    </div>


  </div>
</template>

<script>
import draggable from "vuedraggable";

export default {
  components: {
    draggable,
  },
  data() {
    return {
      variables: [
        { key: 'X', desc: '账单本金' },
        { key: 'Y', desc: '税额' },
        { key: 'Z', desc: '总金额' }
      ],
      logicoperators: [
        { key: '+', desc: '加号' },
        { key: '-', desc: '减号' },
        { key: '*', desc: '乘号' },
        { key: '/', desc: '除号' },
        { key: '(', desc: '(' },
        { key: ')', desc: ')' }
      ],
      operators: [
        { key: '>', desc: '大于' },
        { key: '>=', desc: '大于等于' },
        { key: '<', desc: '小于' },
        { key: '<=', desc: '小于等于' },
        { key: '==', desc: '等于' },
        { key: '!=', desc: '不等于' },
      ],
      relations: [
        { key: '&&', desc: '且' },
        { key: '||', desc: '或' }
      ],
      numberInput: '',
      formula: '',
      dynamicElements: [],
      validationMessage: '',
      isValid: true,
      validationType: 'condition', // 新增选择框的类型
    };
  },
  methods: {
    appendText(text, type) {
      const element = {
        key: text.key,
        desc: type === 0 ? text.desc : text.key,
      };
      this.dynamicElements.push(element);
      this.updateFormula();
    },
    appendNumber() {
      if (this.numberInput !== '') {
        const element = {
          key: this.numberInput,
          desc: this.numberInput,
        };
        this.dynamicElements.push(element);
        this.numberInput = '';
        this.updateFormula();
      }
    },
    deleteElement(index) {
      this.dynamicElements.splice(index, 1);
      this.updateFormula();
    },
    updateFormula() {
      this.formula = this.dynamicElements.map(el => el.key).join(' ');
    },
    reset() {
      this.dynamicElements = [];  // 清空动态元素
      this.formula = '';          // 重置公式
      this.numberInput = '';      // 清空数字输入
    },
  },
};
</script>

<style>
.formula-editor {
  border: 1px solid #dcdfe6;
  padding: 20px;
  width: 80%;
  background-color: #f9f9f9;
  border-radius: 4px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.toolbar {
  margin-bottom: 20px;
}

.toolbar button {
  margin-right: 10px;
  padding: 6px 14px;
  background-color: #409eff;
  color: #fff;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  transition: background-color 0.3s;
}

.toolbar button:hover {
  background-color: #66b1ff;
}

.toolbar input {
  height: 30px;
  margin-right: 10px;
  padding: 4px 10px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  transition: border-color 0.3s;
}

.toolbar input:focus {
  border-color: #409eff;
}

.editor {
  min-height: 50px;
  border: 1px solid #ebeef5;
  padding: 10px;
  border-radius: 4px;
  background-color: #fff;
  white-space: pre-wrap;
  word-wrap: break-word;
  margin-top: 10px;
}

.result {
  margin-top: 20px;
  font-size: 16px;
  color: #606266;
}

.row {
  padding-bottom: 15px;
}

.dynamic-span {
  position: relative;
  background-color: #ecf5ff;
  padding: 6px 12px;
  margin-right: 5px;
  border-radius: 4px;
  display: inline-block;
  font-size: 14px;
  color: #409eff;
}

.delete-btn {
  display: none; /* 默认隐藏 */
  color: #f56c6c;
  cursor: pointer;
  position: absolute;
  top: 0;
  right: -5px;
  transform: translateY(-50%);
  background-color: white;
  border: 1px solid #f56c6c;
  border-radius: 50%;
  width: 20px;
  height: 20px;
  text-align: center;
  line-height: 18px;
  font-size: 12px;
}

.dynamic-span:hover .delete-btn {
  display: inline-block; /* 悬浮时显示 */
}

.dynamic-span:hover {
  background-color: #c6e2ff;
}

.validation-result {
  margin-top: 10px;
  padding: 10px;
  border-radius: 4px;
}

.error {
  background-color: #f5c6cb;
  color: #721c24;
}

.success {
  background-color: #c3e6cb;
  color: #155724;
}
</style>


评论