You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue.js发票交易功能开发:点击按钮动态添加对应行输入项需求咨询

实现方案

核心思路

  • 给每个商品行新增3个布尔类型的显示控制字段,默认值都为false,分别控制备注、固定折扣、折扣率输入区域的显隐
  • 点击对应添加按钮时,仅将当前行对应控制字段设为true,点击删除按钮则设为false并清空对应字段值
  • 点击固定折扣/折扣率按钮时自动隐藏另一类折扣输入区域,满足每行最多1个折扣项的要求

修改后的Vue逻辑代码

const app = new Vue({
    el: "#app",
    data: {
        invoiceItems: [
            {
                name: "",
                quantity: 0,
                unit_price: 0,
                vat_rate: 18,
                net_total: 0,
                description: '',
                discount_value: 0,
                discount_type: 'dollar',
                discount_rate:'usd',
                // 新增显隐控制字段
                showDesc: false,
                showDiscount: false,
                showDiscountRate: false
            },
        ],
    },
    methods: {
        addInvoice() {
            this.invoiceItems.push({
                name: "",
                quantity: 0,
                unit_price: 0,
                vat_rate: 18,
                net_total: 0,
                description: '',
                discount_value: 0,
                discount_type: 'dollar',
                discount_rate:'usd',
                showDesc: false,
                showDiscount: false,
                showDiscountRate: false
            });
        },
        removeIncoiceItem(index) {
            this.invoiceItems.splice(index, 1);
        },
        // 新增切换显隐方法
        toggleDesc(index) {
            this.invoiceItems[index].showDesc = true
        },
        toggleDiscount(index) {
            this.invoiceItems[index].showDiscount = true
            // 隐藏另一类折扣输入
            this.invoiceItems[index].showDiscountRate = false
        },
        toggleDiscountRate(index) {
            this.invoiceItems[index].showDiscountRate = true
            // 隐藏另一类折扣输入
            this.invoiceItems[index].showDiscount = false
        },
        // 新增删除对应项方法
        deleteDesc(index) {
            this.invoiceItems[index].showDesc = false
            this.invoiceItems[index].description = ''
        },
        deleteDiscount(index) {
            this.invoiceItems[index].showDiscount = false
            this.invoiceItems[index].discount_value = 0
        },
        deleteDiscountRate(index) {
            this.invoiceItems[index].showDiscountRate = false
            this.invoiceItems[index].discount_rate = 'usd'
        }
    },
});

修改后的HTML代码

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet">

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.js"></script>
<div id="app">
  <section class="container">
    <div class="row">
      <table class="table">
        <thead class="thead-dark">
          <tr>
            <th style="width:17%">Name</th>
            <th style="width:14%">Unit Price</th>
            <th style="width:15%">Vat Rate</th>
            <th style="width:20%">Action</th>
          </tr>
        </thead>
      </table>
      <div v-for="(item, index) in invoiceItems" :key="index" style="margin-bottom: 10px">
        <div class="row">
          <div class="col-md-2">
            <input type="text" v-model="item.name">
          </div>
          <div class="col-md-2">
            <input type="text" v-model="item.unit_price">
          </div>
          <div class="col-md-2">
            <input type="text" v-model="item.net_total">
          </div>
          <div class="col-md-5">
            <button class="btn btn-primary btn-sm" @click="toggleDesc(index)">Add Description</button>
            <button class="btn btn-secondary btn-sm" @click="toggleDiscount(index)">Add Discount</button>
            <button class="btn btn-warning btn-sm" @click="toggleDiscountRate(index)">Add discount rate</button>
            <button class="btn btn-danger btn-sm" @click="removeIncoiceItem(index)">X</button>
          </div>
          <div  class="row" style="margin-top:20px;">
            <!-- 备注输入区域 -->
            <template v-if="item.showDesc">
              <div class="col-md-2">
                <input type="text" placeholder="description" v-model="item.description">
              </div>
              <div class="col-md-2">
                <button class="btn btn-danger btn-sm" @click="deleteDesc(index)">Delete Desc.</button>
              </div>
            </template>
            <!-- 固定折扣输入区域 -->
            <template v-if="item.showDiscount">
              <div class="col-md-3">
                <div class="input-group">
                  <input type="text" placeholder="discount_value" v-model="item.discount_value">
                  <select class="form-select-new" v-model="item.discount_type">
                    <option value="dollar">USD</option>
                    <option value="percent">%</option>
                  </select>
                </div>
              </div>
              <div class="col-md-1">
                <button class="btn btn-danger btn-sm" @click="deleteDiscount(index)">Delete Disc.</button>
              </div>
            </template>
            <!-- 折扣率输入区域 -->
            <template v-if="item.showDiscountRate">
              <div class="col-md-2">
                <input type="text" placeholder="discount rate" v-model="item.discount_rate">
              </div>
              <div class="col-md-2">
                <button class="btn btn-danger btn-sm" @click="deleteDiscountRate(index)">Delete discount rate</button>
              </div>
            </template>
          </div>
        </div>
        <hr>
      </div>
      <hr>
      <div style="margin-top:10px">
        <button class="btn btn-warning" @click="addInvoice()"> Add Item</button>
      </div>
    </div>
  </section>
</div>

逻辑说明

  • 初始状态所有扩展输入区域默认隐藏,仅展示商品基础字段与操作按钮
  • 点击对应添加按钮后仅当前行的目标输入区域显示,其他行不受影响
  • 切换折扣类型时自动隐藏已激活的另一类折扣输入,满足单行仅1个折扣项的要求
  • 点击删除按钮时隐藏对应输入区域并清空已输入的内容,避免残留数据影响后续计算

内容的提问来源于stack exchange,提问作者Selaminko Elam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 10:27:02