如何在 Vue 组件中格式化货币?

How do I format currencies in a Vue component?

我的 Vue 组件是这样的:

<template>
    <div>
        <div class="panel-group"v-for="item in list">
            <div class="col-md-8">
                <small>
                   Total: <b>{{ item.total }}</b>
                </small>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        ...
        computed: {
            list: function() {
                return this.$store.state.transaction.list
            },
            ...
        }
    }
</script>

{{ item.total }}的结果是

26000000

但我想把它格式化成这样:

26.000.000,00

在jquery或javascript,我可以做到

但是,在vue组件中如何实现呢?

UPDATE: I suggest using a solution with filters, provided by @Jess.

我会为此编写一个方法,然后在需要格式化价格的地方,您只需将方法放在模板中并向下传递值即可

methods: {
    formatPrice(value) {
        let val = (value/1).toFixed(2).replace('.', ',')
        return val.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".")
    }
}

然后在模板中:

<template>
    <div>
        <div class="panel-group"v-for="item in list">
            <div class="col-md-8">
                <small>
                   Total: <b>{{ formatPrice(item.total) }}</b>
                </small>
            </div>
        </div>
    </div>
</template>

顺便说一句 - 我并没有太在意替换和正则表达式。有待改进。enter code here

Vue.filter('tableCurrency', num => {
  if (!num) {
    return '0.00';
  }
  const number = (num / 1).toFixed(2).replace(',', '.');
  return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
});

@RoyJ 的评论提出了很好的建议。在模板中,您可以只使用内置的本地化字符串:

<small>
     Total: <b>{{ item.total.toLocaleString() }}</b>
</small>

它在某些较旧的浏览器中不受支持,但如果您的目标是 IE 11 及更高版本,则应该没问题。

已接受答案的准确性存在问题。

此测试中的 round(value, decimals) 函数有效。 与简单的 toFixed 示例不同。

这是对 toFixed 与 round 方法的测试。

http://www.jacklmoore.com/notes/rounding-in-javascript/

  Number.prototype.format = function(n) {
      return this.toFixed(Math.max(0, ~~n));
  };
  function round(value, decimals) {
    return Number(Math.round(value+'e'+decimals)+'e-'+decimals);
  }

  // can anyone tell me why these are equivalent for  50.005, and 1050.005 through 8150.005 (increments of 50)

  var round_to = 2;
  var maxInt = 1500000;
  var equalRound = '<h1>BEGIN HERE</h1><div class="matches">';
  var increment = 50;
  var round_from = 0.005;
  var expected = 0.01;
  var lastWasMatch = true;

  for( var n = 0; n < maxInt; n=n+increment){
    var data = {};
    var numberCheck = parseFloat(n + round_from);
    data.original = numberCheck * 1;
    data.expected =  Number(n + expected) * 1;
    data.formatIt = Number(numberCheck).format(round_to) * 1;
    data.roundIt = round(numberCheck, round_to).toFixed(round_to) * 1;
    data.numberIt = Number(numberCheck).toFixed(round_to) * 1;
    //console.log(data);

    if( data.roundIt !== data.formatIt || data.formatIt !== data.numberIt ||
       data.roundIt !== data.numberIt || data.roundIt != data.expected
      ){
        if(lastWasMatch){
          equalRound = equalRound + '</div><div class="errors"> <hr/> Did Not Round UP <hr/>' ;
            document.write(' <h3>EXAMPLE: Did Not Round UP: ' + numberCheck + '</h3><br /><hr/> ');
            document.write('expected: '+data.expected + ' :: ' + (typeof data.expected)  + '<br />');
            document.write('format: '+data.formatIt + ' :: ' + (typeof data.formatIt)  + '<br />');
            document.write('round : '+data.roundIt + ' :: ' + (typeof data.roundIt)  + '<br />');
            document.write('number: '+data.numberIt + ' :: ' + (typeof data.numberIt)  + '<br />');
            lastWasMatch=false;
        }
        equalRound = equalRound + ', ' + numberCheck;
    } else {
        if(!lastWasMatch){
          equalRound = equalRound + '</div><div class="matches"> <hr/> All Rounded UP! <hr/>' ;
        } {
            lastWasMatch=true;
        }
        equalRound = equalRound + ', ' + numberCheck;
    }
  }
  document.write('equalRound: '+equalRound + '</div><br />');

mixin 示例

  export default {
    methods: {
      roundFormat: function (value, decimals) {
        return Number(Math.round(value+'e'+decimals)+'e-'+decimals).toFixed(decimals);
      },
      currencyFormat: function (value, decimals, symbol='$') {
        return symbol + this.roundFormat(value,2);
      }
    }
  }

您可以编写自己的代码来格式化货币,但这只是目前的解决方案 - 当您的应用增长时,您可能需要其他货币。

这里还有一个问题:

  1. 对于 EN-us - 美元符号始终在货币之前 - $2.00,
  2. 对于选定的 PL,您 return 在 2,00 zł 这样的金额后签名。

我认为最好的选择是使用复杂的国际化解决方案,例如库 vue-i18n( http://kazupon.github.io/vue-i18n/).

我使用这个插件,我不用担心这样的事情。请查看文档 - 它非常简单:

http://kazupon.github.io/vue-i18n/guide/number.html

所以你只需使用:

<div id="app">
  <p>{{ $n(100, 'currency') }}</p>
</div>

并设置 EN-us 得到 $100.00:

<div id="app">
  <p>0.00</p>
</div>

或设置 PL 以获得 100,00 zł:

<div id="app">
  <p>100,00 zł</p>
</div>

此插件还提供不同的功能,如翻译和日期格式。

我创建了一个过滤器。过滤器可用于任何页面。

Vue.filter('toCurrency', function (value) {
    if (typeof value !== "number") {
        return value;
    }
    var formatter = new Intl.NumberFormat('en-US', {
        style: 'currency',
        currency: 'USD'
    });
    return formatter.format(value);
});

然后我可以像这样使用这个过滤器:

        <td class="text-right">
            {{ invoice.fees | toCurrency }}
        </td>

我使用这些相关答案来帮助实施过滤器:

  • How to format numbers as currency strings
  • Check whether variable is number or string in JavaScript

对于 vuejs 2,您可以使用 vue2-filters,它还有其他优点。

npm install vue2-filters


import Vue from 'vue'
import Vue2Filters from 'vue2-filters'

Vue.use(Vue2Filters)

然后像这样使用它:

{{ amount | currency }} // 12345 => ,345.00

参考:https://www.npmjs.com/package/vue2-filters

我使用了@Jess 提出的自定义过滤器解决方案,但在我的项目中,我们将 Vue 与 TypeScript 结合使用。 这是使用 TypeScript 和 class 装饰器的样子:

import Component from 'vue-class-component';
import { Filter } from 'vue-class-decorator';

@Component
export default class Home extends Vue {

  @Filter('toCurrency')
  private toCurrency(value: number): string {
    if (isNaN(value)) {
        return '';
    }

    var formatter = new Intl.NumberFormat('en-US', {
        style: 'currency',
        currency: 'USD',
        minimumFractionDigits: 0
    });
    return formatter.format(value);
  }
}

在此示例中,过滤器只能在组件内部使用。我还没有尝试将其实现为全局过滤器。

你可以使用这个例子

formatPrice(value) {
  return value.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, ',');
},

试试这个:

methods: {
    formatPrice(value) {
        var formatter = new Intl.NumberFormat('en-US', {
            style: 'currency',
            currency: 'PHP',
            minimumFractionDigits: 2
        });
        return formatter.format(value);
    },
}

那么你可以这样称呼它:

{{ formatPrice(item.total) }}

numeral.js 是一个 JavaScript 用于格式化和操作数字的库。

您可以使用它轻松格式化货币。

例如,

// price = 1200
{numeral(price).format(`[=10=],0.00`)}

// result ,200.00

这是文档。 http://numeraljs.com/