web-dev-qa-db-fra.com

Comment formater les devises dans un composant Vue?

Mon composant Vue ressemble à ceci:

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

Le résultat de {{ item.total }} est

26000000

Mais je veux que le format soit comme ça:

26.000.000,00

En jquery ou javascript, je peux le faire

Mais comment faire dans le composant vue?

50
samuel toh

MISE À JOUR: Je suggère d'utiliser une solution avec des filtres, fournie par @Jess.

J'écrirais la méthode pour cela, et là où vous avez besoin de formater le prix, vous pouvez simplement mettre la méthode dans un modèle et transmettre la valeur

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

Et puis dans le template:

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

BTW - Je n'ai pas mis beaucoup d'attention sur le remplacement et l'expression régulière.Il pourrait être amélioré.

56
Belmin Bedak

J'ai créé un filtre. Le filtre peut être utilisé dans n'importe quelle page.

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

Ensuite, je peux utiliser ce filtre comme ceci:

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

J'ai utilisé ces réponses pour aider à la mise en œuvre du filtre:

104
Jess

Avec vuejs 2, vous pouvez utiliser vue2-filters, qui contient également d'autres avantages.

npm install vue2-filters


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

Vue.use(Vue2Filters)

Alors utilisez-le comme suit:

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

Réf.: https://www.npmjs.com/package/vue2-filters

13
Yao Liu

Vous pouvez formater la devise en écrivant votre propre code, mais il ne s'agit que d'une solution pour le moment. Lorsque votre application grandira, vous aurez besoin d'autres devises.

Il y a un autre problème avec ceci:

  1. Pour EN-us - le signe dolar est toujours avant la devise - 2,00 $,
  2. Pour PL sélectionné, vous retournez signe après montant comme 2,00 zł.

Je pense que la meilleure option consiste à utiliser une solution complexe pour l'internationalisation, par exemple. bibliothèque vue-i18n ( http://kazupon.github.io/vue-i18n/ ).

J'utilise ce plugin et je n'ai pas à m'inquiéter de telles choses. S'il vous plaît consulter la documentation - c'est très simple:

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

alors vous utilisez juste:

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

et définissez EN-us pour obtenir 100,00 $ :

<div id="app">
  <p>$100.00</p>
</div>

ou définir PL pour obtenir 100,00 zł :

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

Ce plugin fournit également différentes fonctionnalités telles que les traductions et le formatage de la date.

9
Arkowsky

Le commentaire de @RoyJ a une excellente suggestion. Dans le modèle, vous pouvez simplement utiliser des chaînes localisées intégrées:

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

Il n'est pas pris en charge par certains des anciens navigateurs, mais si vous ciblez IE 11 et versions ultérieures, tout devrait bien se passer.

8
AaronBaker

La précision de la réponse acceptée pose problème.

La fonction round (valeur, décimales) de ce test fonctionne. contrairement à l'exemple toFixed simple.

ceci est un test de la méthode 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 />');

exemple de mix

  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
Artistan