Vueコンポーネントで通貨をフォーマットするにはどうすればよいですか?


85

私の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
Vueで実行できるようにjavascriptで実行できる場合は、計算されたプロパティを使用してjavascriptコードを返します。
Happyriri 2017

回答:


83

更新:@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


12
組み込みのローカライズされた通貨フォーマットについては、developer.mozilla.org / en-US / docs / Web / JavaScript / Reference /…も参照してください。
ロイJ

@RoyJ良いキャッチ。前のプロジェクトから正規表現をコピーしたところです。基本的に、彼はメソッドから必要に応じて値を返すことができました。
Belmin Bedak 2017

@BelminBedakどう思いますreturn (value/1).toFixed(2).toLocalString();か?
レトロバーティゴ2018

動作しますが、すべての小数をコンマに置き換えます
Dylan Glockler 2018年

computed代わりに使ってみませんか?
localhostの

191

フィルタを作成しました。フィルタはどのページでも使用できます。

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
私の男!私はあなたがこれをすることができるとさえ知りませんでした。彼らのほとんどがこの種のことをしていたので、感謝は私の通貨の問題を解決し、私のミックスインをクリーンアップしました。
マイナス2018

2
これが正しい答えです
ierdna 2018年

Intl最高ではない持ってサポート
ИльяЗеленько

1
isNaN(parseFloat(value))ではなくどうtypeof value !== "number"ですか?
RonnyKnoxville

1
データベースが文字列を返すことがあるので、条件付きの部分を変更します。おそらく、その条件付きの数値に文字列をキャストする方が良いでしょう。
アンドレスフェリペ

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


11

独自のコードを記述して通貨をフォーマットすることはできますが、それは今のところ解決策にすぎません。アプリが成長すると、他の通貨が必要になる可能性があります。

これには別の問題があります:

  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アンドレ

5

@Jessによって提案されたカスタムフィルターソリューションを使用しましたが、私のプロジェクトでは、TypeScriptと一緒にVueを使用しています。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);
  }
}

この例では、フィルターはコンポーネント内でのみ使用できます。私はまだそれをグローバルフィルターとして実装しようとはしていません。


2

この例を使用できます

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

1

受け入れられた回答の精度に問題があります。

このテストのround(value、decimals)関数は機能します。 単純なtoFixedの例とは異なります。

これは、toFixed vsroundメソッドのテストです。

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 2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.