¿Cómo formateo monedas en un componente Vue?


Mi componente Vue es así:

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

El resultado de {{ item.total }} es

26000000

Pero quiero que el formato sea así:

26.000.000,00

En jquery o javascript, puedo hacerlo

Pero, ¿Cómo hacerlo en el componente vue?

Author: Mridang Agarwalla, 2017-04-04

6 answers

Escribiría el método para eso, y luego donde necesita formatear el precio, puede poner el método en la plantilla y pasar el valor

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

Y luego en la plantilla:

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

POR cierto-No puse demasiado cuidado en la sustitución y regular expression.It podría mejorarse.

 36
Author: Belmin Bedak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-04 13:20:46

He creado un filtro. El filtro se puede utilizar en cualquier página.

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

Entonces puedo usar este filtro así:

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

Usé estas respuestas relacionadas para ayudar con la implementación del filtro:

 42
Author: Jess,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-31 19:55:44

Puede formatear la moneda escribiendo su propio código, pero es la solución por el momento: cuando su aplicación crezca, puede necesitar otras monedas.

Hay otro problema con esto:

  1. Para EN-us - dolar signo es siempre antes de la moneda - $2.00,
  2. Para el PL seleccionado devolver signo después de la cantidad como 2,00 zł.

Creo que la mejor opción es utilizar una solución compleja para la internacionalización, por ejemplo, biblioteca vue-i18n( http://kazupon.github.io/vue-i18n/).

Uso este plugin y no tengo que preocuparme por tales cosas. Por favor mira la documentación - es realmente simple:

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

Así que solo usa:

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

Y establece EN-us para obtener $100.00:

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

O establezca PL para obtener 100,00 zł :

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

Este plugin también proporciona diferentes características como traducciones y formato de fecha.

 6
Author: Arkowsky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-31 09:02:49

El comentario de @RoyJ tiene una gran sugerencia. En la plantilla solo puedes usar cadenas localizadas integradas:

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

No es compatible con algunos de los navegadores más antiguos, pero si está apuntando a IE 11 y posteriores, debería estar bien.

 4
Author: AaronBaker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-02 17:49:17

Con vuejs 2, puedes usar los filtros vue2, que también tienen otras ventajas.

npm install vue2-filters


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

Vue.use(Vue2Filters)

Entonces úsalo así:

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

Ref: https://www.npmjs.com/package/vue2-filters

 4
Author: Yao Liu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-30 01:41:51

Hay problemas con la precisión de la respuesta aceptada.

La función round (valor, decimales) en esta prueba funciona. a diferencia del simple ejemplo toFixed.

Esta es una prueba del método 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 />');

Ejemplo 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
Author: Artistan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-19 18:21:10