Vuejs2-如何从方法调用过滤器函数?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (2585)

我正在使用“moneyFormat”过滤器来格式化货币值。它正在格式化已定义的值。我想格式化动态值。因此我通过一个名为“displayValue”的方法调用了filter函数,但是我收到了错误

并且给定的输入字段也没有更新。

这是我的代码:

<template>
    <b-card>
        <div class="panel-body" id="app">
            <table class="table table-hover">
                <thead>
                    <tr>
                        <th style="width: 20px;">No.</th>
                        <th style="width: 330px;">Description</th>
                        <th style="width: 130px;" class="text-right">Charges</th>
                        <th style="width: 130px;">Total</th>
                        <th style="width: 130px;"></th>
                    </tr>
                </thead>
                <tbody>
                    <tr v-for="(row, index) in rows" :key="row.qty">
                        <td>
                            {{ index +1 }}
                        </td>
                        <td>

                        <select name="" id="" class="form-control" v-model="row.billChgDesc">
                            <option v-for="option in billChgDescOpt" v-bind:value="option.value" 
                                :key="option.value"> {{ option.text }} 
                            </option>
                        </select>
                        </td>

                                <td> 
                                  <input @input="displayValue" class="form-control text-right" type="text" v-model="row.charges"  data-type="currency" v-validate="'required'" :name="'charges' + index">
                                     <span v-show="vErrors.has('charges' + index)" class="is-danger">{{ vErrors.first('charges' + index) }}</span>
                                <td>
                                    <input class="form-control text-right" :value="row.qty * row.charges | moneyFormat" number readonly />
                                    <input type="hidden" :value="row.qty * row.charges * row.tax / 100"  number/>
                                </td>

                                <td>
                                    <button class="btn btn-primary btn-sm" @click="addRow(index)"><i class="fa fa-plus"></i></button>
                                    <button class="btn btn-danger btn-sm" @click="removeRow(index)"><i class="fa fa-minus"></i></button>
                                </td>
                            </tr>
                </tbody>
                <tfoot>
                    <tr>
                        <td colspan="3" class="text-right">DELIVERY</td>
                        <td colspan="1" class="text-right"><input class="form-control text-right" v-model="delivery" number/></td>
                        <td></td>
                    </tr>
                </tfoot>
            </table>

        </div>
    </b-card>
</template>

<script>
import Vue from 'vue'
import accounting from 'accounting'

export default {

filters:{
moneyFormat: function (val){
     if (val > 0) {
            return accounting.formatMoney(val, " ₹ ", 2, ",", ".");
        }
}
},
   data: function () {
    return {
        billChgDescOpt: [
            { value: '', text: 'Select' },
            { value: 'M', text: 'Maintenance Fee'},
            { value: 'W', text: 'Water Charges'},
            { value: 'P', text: 'Penalty Fee'},
            ],
        rows: [
            {qty: 5, billChgDesc: '', charges: 55.20, tax: 10},
            {qty: 19, billChgDesc: '', charges: 1255.20, tax: 20},
        ],
        grandtotal: 0,
        delivery: 40
    }

  },
    computed: {
        total: function () {
            var t = 0;
            $.each(this.rows, function (i, e) {
                t += accounting.unformat(e.total, ",");
            });
            return t;
        },
        taxtotal: function () {
            var tt = 0;
            $.each(this.rows, function (i, e) {
                tt += accounting.unformat(e.tax_amount, ",");
            });
            return tt;
        }
    },
    methods: {

        addRow: function (index) {
            try {
                this.rows.splice(index + 1, 0, {});
            } catch(e)
            {
                console.log(e);
            }
        },
        removeRow: function (index) {
            this.rows.splice(index, 1);
        },
        displayValue:function (e) {
            var value = e.target.value
         var a = this.filters.moneyFormat(value);
         return a;
        }
    }
}
</script>

<style lang="scss" scoped>
.is-danger{
  color:  RED;
}
</style>
提问于
用户回答回答于

如前所述,如果你想使用过滤器,你需要this.$options.filters.moneyFormat(value)

你要达到的目的是在输入中呈现MoneyFormat,并且显示的值是v-model。这是你必须格式化的。

这样,你就可以初始化一个新的数据属性,其中每个属性都是填充的。row.charges在挂载上格式化:

data: function () {
  return {
    rows: [
      //...
    ],
    currentCharges: []
  }
},

mounted() {
  this.rows.forEach(row => {
    let formattedCharges = this.$options.filters.moneyFormat(row.charges)
    this.currentCharges.push(formattedCharges)
  })
},

并使用这些数据来满足你的输入:

<tr v-for="(row, index) in rows">
  <td> 
    <input v-model="currentCharges[index]" @input="displayValue($event, index)">
  <td>

保持电流row.charges更新后,在v模型更新时重新分配它:

methods: {
  displayValue:function (e, index) {
    // the target value is a string like this " ₹ 55.20"
    // split it and convert the last element to Float type
    let arrValue = e.target.value.split(" ")
    let parseValue = parseFloat(arrValue[arrValue.length -1])

    // reassign the row.charges with the new float value
    this.rows[index].charges = parseValue
  }
},
用户回答回答于

你可以:

this.$options.filters.moneyFormat(value)

对于全局过滤器,第一组:

Vue.prototype.$filters = Vue.options.filters

然后:

this.$filters.foo

编辑:

仔细查看你的代码,没有使用filter作为一个Vue过滤器,并且只从一个点(方法)调用,而不是从HTML调用内联,也许方法本身返回输入的值会更好,例如:

displayValue: function (e) {
    var val = e.target.value
    if (val > 0) {
       return accounting.formatMoney(val, " ₹ ", 2, ",", ".");
    }
} 

扫码关注云+社区

领取腾讯云代金券

玩转腾讯云 有奖征文活动