vue js中的动态定价计算器

Posted

技术标签:

【中文标题】vue js中的动态定价计算器【英文标题】:Dynamic pricing calculator in vue js 【发布时间】:2021-06-24 00:48:09 【问题描述】:

*已编辑

我正在使用 vue js 构建一个动态定价计算器功能。我已经编写了代码,但仍然存在一些问题使我制作的功能无法正常工作。我有一个下拉菜单,单击它会显示不同的选项卡和不同的内容(动态组件)。而且我还有一张详细信息和价格的估价卡,每个项目都可以删除。

我有几个问题如下:

    当我在Storage选项卡上,选择几个选项后提交数据时,软件选项卡的详细信息和价格也出现在估算卡中。我想要的只是Storage 的定价细节。同样,如果我只是在Software 选项卡中提交,那么Software 选项卡中只会显示详细信息和价格。而如果我在SoftwareStorage提交,就会出现两者的结果。

    当我在Storage 选项卡上提交数据并转到Software 选项卡时,估算卡上的价格详细信息消失了。我希望数据仍然出现。如果我使用 <keep-alive> 是不可能的,因为它不是动态组件。

    我在估算卡中有删除按钮项目。我想要的将根据单击的选项删除该项目。但仍然不能很好地工作。

目前,我只有 2 个选项卡,存储和软件。如果我有其他选项卡,如何使这个系统动态化?

谁能帮我解决这个问题并一步一步解释?

这是我在 Codesandbox 上制作的代码:https://codesandbox.io/s/dynamic-price-calculator-o77ig

【问题讨论】:

【参考方案1】:

这是完成这项工作的一组非常粗糙的组件 - 没有 SUBMIT 按钮。

Vue.component("ProductSetup", 
  props: ['productKey', 'product'],
  methods: 
    handleInputChange(e) 
      this.$emit("update:product-type", 
        ...e,
        product: this.productKey,
      )
    ,
    handleQuantityChange(e) 
      this.$emit("update:product-quantity", 
        ...e,
        product: this.productKey,
      )
    ,
  ,
  template: `
    <div>
      <label
        v-for="(val, key) in product.types"
        :key="key"
      >
         key 
        <input
          type="radio"
          :value="val"
          :name="productKey"
          @change="() => handleInputChange( type: key )"
        />
      </label>
      <input
        type="number"
        min="0"
        @input="(e) => handleQuantityChange( quantity: e.target.value )"
      />
    </div>
  `,
)

Vue.component("PriceEstimate", 
  props: ["products"],
  template: `
    <div>
      <div
        v-for="(product, productKey) in products"
      >
         productKey <br />
         productKey   product.chosen :  product.types[product.chosen] <br />
        Quantity  productKey :  product.quantity * product.pricePerPiece <br />
        TOTAL:  product.types[product.chosen] + product.quantity * product.pricePerPiece 
      </div>
    </div>
  `,
)

new Vue(
  el: "#app",
  computed: 
    estimates() 
      return Object.fromEntries(
        Object.entries(
          this.products
        ).filter(([key, val]) => 
          return val.chosen && val.quantity
        )
      )
    ,
  ,
  data() 
    return 
      products: 
        storage: 
          chosen: null,
          types: 
            type1: 60,
            type2: 70,
          ,
          pricePerPiece: 20,
          quantity: null,
        ,
        os: 
          chosen: null,
          types: 
            os1: 60,
            os2: 70,
            os3: 80,
          ,
          pricePerPiece: 35,
          quantity: null,
        ,
      ,
    
  ,
  methods: 
    handleUpdateProduct(
      type,
      product
    ) 
      this.products[product]["chosen"] = type
    ,
    handleUpdateQuantity(
      quantity,
      product
    ) 
      this.products[product]["quantity"] = quantity
    
  ,
  template: `
    <div>
      <div
        v-for="(obj, product) in products"
      >
        Chosen  product :  obj.chosen <br />
        Quantity of  product :  obj.quantity 
        <hr />
        <product-setup
          :product-key="product"
          :product="obj"
          @update:product-type="(e) => handleUpdateProduct(e)"
          @update:product-quantity="(e) => handleUpdateQuantity(e)"
        />
        <hr />
      </div>
      <price-estimate
        :products="estimates"
      />
    </div>
  `,
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app"></div>

【讨论】:

【参考方案2】:

问题出在 priceEstimationData 接收到的参数中,它确实有 servicesDuration 和 servicesTypePrice。

在 ServiceCalculator.vue 中,“数据”是:

var data = 
    servicesTypeName: selectedServicesType.name,
    servicesTypeValue: selectedServicesType.value,
    qunantity: this.quantiti,
    durationServices: this.durationServices,
;

您还必须传递属性 servicesDuration 和 servicesTypePrice。

问候

【讨论】:

我添加 servicesTypePrice: this.servicesTypePrice, serviceDuration: this.servicesDuration 仍然无法正常工作 我看到的是设置属性 priceEstimationData 时没有一致性。调用“setPriceEstimationData”时,您必须传递所有属性。作为快速修复,您可以在“PriceEstimation.vue”中执行此操作: watch: priceEstimationData: function (data) ... this.servicesType = data.servicesTypeName; this.servicesTypePrice = data.servicesTypeValue ?数据服务类型值:0; this.servicesQuantity = 数据.数量; this.servicesDuration = data.durationServices ? data.durationServices:0; ... ,问候【参考方案3】:
    您必须使 priceEstimationData 动态化。您可以在不使用手表的情况下显示来自道具的数据。我在这里只提供一些代码。如需完整版,请前往代码框。
<!-- PriceEstimation.vue -->

<template v-if="priceEstimationData">
    <div
      :key="id"
      v-for="(data, id) in priceEstimationData"
      class="estimation-category"
    >
      <div class="category-price d-flex justify-content-between">
       data ? data.type[0].toUpperCase() + data.type.slice(1) : ""
        <a href="#" @click="removeItem(id)">Delete</a>
      </div>
      <table class="table table-borderless">
        <tbody>
          <tr>
            <td>
              <p>
                Storage Type: <span> data.typeName </span>
              </p>
              <p>
                Quantity Storage: <span> data.qunantity </span>
              </p>
              <p>
                Duration Storage: <span> data.duration </span>
              </p>
            </td>
            <td class="text-right">
              <p>$ data.typeValue </p>
              <p>$ data.qunantity * data.quantityPrice </p>
              <p>$ data.duration * data.durationPrice </p>
            </td>
          </tr>
        </tbody>
      </table>
    </div>
  </template>
    查看您的代码后。我注意到您正在使用 watch 属性。我已经删除了 watch 属性以使估计数据仍然存在。请参阅下面的代码
// TheCalculator.vue

// remove watch that makes the priceEstimationData null
/* watch: 
 selectedTab: function () 
   this.priceEstimationData = null;
 ,
, */
computed: 
 selectedTabProps() 
   return this.selectedTab === "storage-calculator"
     ?  event: this.setPriceEstimationData 
     : null;
 ,
,
    我已修改您的代码并将 removeItem 方法移至父级。因为孩子只读取数据。见下文
// TheCalculator.vue

methods: 
 setSelectedTab(tab) 
  this.selectedTab = tab;
 ,
 setPriceEstimationData(data) 
  this.priceEstimationData.push(data);
 ,
 removeItem(id) 
  // remove findIndex function
  this.priceEstimationData.splice(id, 1);
 ,
,

我修改了TheCalculator.vuePriceEstimation.vueServiceCalculator.vueStorageCalculator.vue

编辑

我已修复 ServiceCalculator.vue 中的持续时间错误

// ServiceCalculator.vue

// fixes duration bug
updateDurationServices(val) 
 this.duration = val;
,

代码沙盒:https://codesandbox.io/s/dynamic-price-calculator-forked-ls7n6

享受吧!

【讨论】:

以上是关于vue js中的动态定价计算器的主要内容,如果未能解决你的问题,请参考以下文章

Vue.js 3 html 动态类基于计算属性传递参数

在 Vue JS 中使用计算与动态对象

Vue.js 中的多个 .include 计算?

vuejs中的v-for怎样动态增加循环数据

使用 Vue.js 中的方法过滤计算属性的数组

从 Vue.js 2 中的计算属性中推送到数组