【问题标题】:如何在 Vue 组件中格式化货币?
【发布时间】:2017-08-29 16:47:49
【问题描述】:

我的 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 组件中实现呢?

【问题讨论】:

  • 如果你可以在 javascript 中实现,那么你可以在 Vue 中实现...使用计算属性并返回 javascript 代码。

标签: vue.js vuejs2 vue-component vuex


【解决方案1】:

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

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>

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

【讨论】:

  • 我的男人!我什至不知道你能做到这一点。谢谢解决了我的货币问题并清理了我的 mixin,因为他们中的大多数人都在做这种事情。
  • 这是正确的答案
  • isNaN(parseFloat(value)) 而不是typeof value !== "number" 怎么样?
  • 我会更改条件部分,因为有时数据库返回字符串,也许将字符串转换为条件中的数字会更好,很好的答案。
  • 奇怪的是这个答案指定了minimumFractionDigits: 0。我希望大多数想要将数字格式化为货币的人会像我一样希望显示 2 个小数位,例如5.90 美元,而不是 5.9 美元。在这种情况下,您可以指定minimumFractionDigits: 2,或者实际上完全不使用该行,因为如果使用style: 'currency',它将默认为2。希望这对某人有所帮助...
【解决方案2】:

更新:我建议使用@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, ',');
});

【讨论】:

  • 另请参阅developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…,了解内置的本地化货币格式。
  • @RoyJ 很好。我只是从以前的一个项目中复制了正则表达式,基本上他可以根据需要从方法中返回值。
  • @BelminBedak 你觉得return (value/1).toFixed(2).toLocalString(); 怎么样?
  • 有效,但用逗号替换所有小数
  • 为什么不改用computed?
【解决方案3】:

使用 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

【讨论】:

    【解决方案4】:

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

    这还有另一个问题:

    1. 对于 EN-us - 美元符号始终位于货币之前 - 2.00 美元,
    2. 对于选定的 PL,您在 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>$100.00</p>
    </div>
    

    或将 PL 设置为 100,00 zł:

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

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

    【讨论】:

    • 我认为这是最好的答案。
    【解决方案5】:

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

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

    一些较旧的浏览器不支持它,但如果你的目标是 IE 11 及更高版本,你应该没问题。

    【讨论】:

    • 就这么简单。确认它有效。感觉应该是选择的答案!
    【解决方案6】:

    我使用了@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);
      }
    }
    

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

    【讨论】:

      【解决方案7】:

      你可以使用这个例子

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

      【讨论】:

        【解决方案8】:

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

        此测试中的 round(value, decimals) 函数有效。 不同于简单的 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);
              }
            }
          }

        【讨论】:

        • 您仍然可以在 .和 , 变化。
        【解决方案9】:

        试试这个:

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

        那么你可以这样称呼:

        {{ formatPrice(item.total) }}
        

        【讨论】:

          【解决方案10】:

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

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

          例如,

          // price = 1200
          {numeral(price).format(`$0,0.00`)}
          
          // result $1,200.00
          

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

          【讨论】:

            猜你喜欢
            • 2021-09-05
            • 2021-12-06
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-04-25
            • 2012-05-31
            • 1970-01-01
            相关资源
            最近更新 更多