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


81

我的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组件中做到这一点?


1
如果可以使用javascript进行操作,那么可以使用Vue ...使用计算属性并返回javascript代码。
Happyriwan

Answers:


82

更新:我建议使用@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


11
另请参阅developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/…,以了解内置的本地化货币格式。
罗伊J

@RoyJ好,我刚刚从上一个项目复制了正则表达式,基本上他可以根据需要从方法中返回值。
Belmin Bedak '17

@BelminBedak你怎么看return (value/1).toFixed(2).toLocalString();
retrovertigo

可行

为什么不使用它computed呢?
本地主机

182

我创建了一个过滤器。该过滤器可以在任何页面中使用。

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

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

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

我使用了以下相关答案来帮助实现过滤器:


5
天哪!我什至不知道你能做到这一点。谢谢解决了我的货币问题,并清理了我的mixins,因为其中大多数都在做这种事情。
Ominus

1
这是正确的答案
ierdna,

Intl还没有最好的支持
ИльяЗеленько

1
怎么样isNaN(parseFloat(value)),而不是typeof value !== "number"
罗尼·诺克斯维尔,

@JackalopeZero:是的,这是一个更好的检查。就我而言。
dotNET

22

使用vuejs 2,您可以使用vue2-filters,它也具有其他优点。

npm install vue2-filters


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

Vue.use(Vue2Filters)

然后像这样使用它:

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

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


10

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

还有另一个问题:

  1. 对于EN-us-美元符号始终先于货币-2.00美元,
  2. 对于选定的PL,您需要在2,00zł之后返回符号。

我认为最好的选择是对国际化使用复杂的解决方案,例如库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>$100.00</p>
</div>

或将PL设置为100,00zł

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

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


8

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

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

某些旧版浏览器不支持此功能,但是如果您以IE 11及更高版本为目标,则应该可以。


像这样简单。确认有效。感觉应该是选定的答案!
UX And​​re

4

我使用了@Jess提出的自定义过滤器解决方案,但在我的项目中,我们将Vue与TypeScript一起使用。这是使用TypeScript和类装饰器的外观:

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);
  }
}

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



1

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

此测试中的round(值,小数)函数有效。 不像简单的toFixed示例。

这是toFixed vs 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 />');

混合示例

  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
您仍然可以val.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".")在此之后使用。和,更改。
Artistan'7
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.