【问题标题】:Calculate sum of dynamically added values with vuejs使用 vuejs 计算动态相加值的总和
【发布时间】:2018-02-18 17:32:54
【问题描述】:

如果在最后一行的第一列中选​​择了选项,我将在表中动态添加带有选择和输入的新行。

看起来像这样https://jsfiddle.net/zgykgery/,所以当您选择“服务”时,会添加新行,并且该行的总价是根据服务价格、默认 10% 的折扣和金额计算的。

我得到的服务价格有点笨拙 :value="item.id+'|'+item.price" 所以我有过滤器从价值中获取它。 但它有效,现在我不知道如何循环遍历所有行和总服务价格,没有折扣、总折扣,然后是全价和服务价格和折扣。

我知道我应该使用计算属性或观察者,但不知道如何。

如何计算表格中这些值的总和并将它们显示在下面的较小表格中?

更新

我是 vue 新手,没有使用计算属性,所以这是我尝试过的,但没有成功:

var Main = {
  data() {
    return {
      rows_top: [{
        service: '',
        position: '',
        visit: '',
        amount: '',
        discount: 10
      }],
      services: [{
          id: 1,
          name: 'Service1',
          price: 100
        },
        {
          id: 2,
          name: 'Service2',
          price: 200
        },
        {
          id: 3,
          name: 'Service3',
          price: 300
        },
      ],
      total_discount: 0,
      total_full_price: 0
    }
  },
  methods: {
    addRow(row, index) {
      // console.log(row)
      if (this.rows_top[this.rows_top.length - 1].service !== '') {
        this.rows_top.push({
          service: '',
          position: '',
          visit: '',
          amount: '',
          discount: 10
        })
      }
    },
    deleteRow(index) {
      this.rows_top.splice(index, 1)
    }
  },
  computed: {
    total_price: () => {
      if (this.rows_top) {
        return this.rows_top.map((r) => {
          return r.amount * this.$options.filters.after_line(r.service)
        })
      }
    }
  },
  filters: {
    after_line: (value) => {
      if (!value) return ''
      let after = value.split('|')
      return after.pop()
    }
  }
}
var Ctor = Vue.extend(Main)
new Ctor().$mount('#app')
@import url("//unpkg.com/element-ui@2.0.11/lib/theme-chalk/index.css");
table {
  border-collapse: collapse
}

table,
th,
td {
  border: 1px solid #ddd
}

th,
td {
  padding: 5px
}

tr:nth-child(odd) {
  background-color: #f9f9f9
}
<script src="//unpkg.com/vue/dist/vue.js"></script>
<script src="//unpkg.com/element-ui@2.2.0/lib/index.js"></script>
<div id="app">
  <template>
  <table>
  <thead>
    <tr>
      <th>Service</th>
      <th>Position</th>
      <th>Visit</th>
      <th>Amount</th>
      <th>Price</th>
      <th>Discount %</th>
      <th>Full price</th>
    </tr>
  </thead>
  <tbody>
    <tr v-for="(row, index) in rows_top">
      <td>
        <el-select placeholder="Select" filterable="filterable" @change="addRow(row, index)" v-model="row.service">
          <el-option v-for="item in services" :key="item.id" :label="item.name" :value="item.id+'|'+item.price"></el-option>
        </el-select>
      </td>
      <td>
        <el-select placeholder="Select" v-model="row.position" multiple="multiple" filterable="filterable" allow-create="allow-create" @change="checkNumber(result, index)"></el-select>
      </td>
      <td>
        <el-select placeholder="Select" v-model="row.visit" allow-create="allow-create" filterable="filterable">
          <el-option v-for="i in 10" :key="i" :label="i" :value="i"></el-option>
        </el-select>
      </td>
      <td>
        <el-select placeholder="Select" v-model="row.amount" allow-create="allow-create" filterable="filterable">
          <el-option v-for="i in 30" :key="i" :label="i" :value="i"></el-option>
        </el-select>
      </td>
      <td>{{ row.service | after_line }}</td>
      <td>
        <el-input v-model="row.discount"></el-input>
      </td>
      <td><span v-if="row.service && row.amount">{{ ($options.filters.after_line(row.service) * row.amount - (($options.filters.after_line(row.service) * row.amount) / 100) * row.discount).toFixed(2) }}</span><span v-else-if="row.service">{{ ($options.filters.after_line(row.service) - ($options.filters.after_line(row.service) / 100) * row.discount).toFixed(2) }}</span>
        <el-button v-if="row.service" icon="el-icon-delete" size="mini" @click="deleteRow(index)" class="push-right"></el-button>
      </td>
    </tr>
  </tbody>
</table><br/>
<table>
  <tr>
    <td>Total price</td>
    <td>{{ total_price }}</td>
  </tr>
  <tr>
    <td>Total discount</td>
    <td>{{ total_discount }}</td>
  </tr>
  <tr>
    <td>Total full price</td>
    <td>{{ total_full_price }}</td>
  </tr>
</table>
</template>
</div>

这里也更新了小提琴,更改时总价仍然为空https://jsfiddle.net/zgykgery/21/

【问题讨论】:

  • 使用computed。只需编写执行计算的函数并进行计算即可。
  • @RoyJ 谢谢,是的,我认为应该使用计算,但我是新手。你能检查我在更新的问题中是否在正确的轨道上?谢谢
  • 欢迎来到 Stack Overflow。请在问题本身中输入一个最小的、完整的、可验证的示例。仅链接到 jsfiddle 是不够的。仅仅在你的问题中写几行是不够的。
  • @gman 好的,我在问题中添加了完整代码

标签: javascript vue.js element-ui


【解决方案1】:

正如@Roy J 所说,只需使用计算函数来获取计算值,知道当来自item 的数据发生变化时它会自动更改

编辑:在使用v-for 循环的情况下,一个简单的method 设计得更好

methods: {
    priceID (item) {
        return item.id + '|' + item.price
    }
}

你会像在你的 Vue 中那样使用它

<tr v-for="(row, index) in rows_top">
  <td>
    <el-select placeholder="Select" filterable="filterable" @change="addRow(row, index)" v-model="row.service">
      <el-option v-for="item in services" :key="item.id" :label="item.name" :value="priceID(item)"></el-option>
    </el-select>
  </td>
  ...

【讨论】:

  • 谢谢,但有了这个我得到那个项目是未定义的。你能检查更新的问题吗?
  • 没有看到 item 变量来自您的 v-for 循环,然后您只需将参数传递给函数(即 priceID),该参数将为 item。但是当您使用 v-for 循环来获取 item 时,使用 computed 毫无意义,因此您可以回退到 methods 中的标准函数。相应地更新了我的答案
  • 谢谢你,但我不知道你是否明白我需要什么。我需要使用该选择动态添加的行中的值总和。就像问题中描述的那样。您提出的这种方法是否能以某种方式帮助我实现这一目标?
  • Ofc,您可以将计算行数所需的任何内容传递给函数!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-11
  • 1970-01-01
  • 2018-02-06
  • 1970-01-01
  • 2021-01-13
相关资源
最近更新 更多