vue.js - page - vue router meta
¿Cómo formateo las monedas en un componente de Vue? (6)
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 vue componente?
Con vuejs 2, puedes usar vue2-filters, que también tiene otros beneficios.
<small>
Total: <b>{{ item.total.toLocaleString() }}</b>
</small>
Entonces utilízalo así:
npm install vue2-filters
import Vue from ''vue''
import Vue2Filters from ''vue2-filters''
Vue.use(Vue2Filters)
El comentario de @RoyJ tiene una gran sugerencia. En la plantilla solo puede usar cadenas localizadas incorporadas:
{{ amount | currency }} // 12345 => $12,345.00
No es compatible con algunos de los navegadores más antiguos, pero si está apuntando a IE 11 y versiones posteriores, debería estar bien.
Escribiría un método para eso, y luego, cuando necesite dar formato al 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 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 me preocupé demasiado por el reemplazo y la expresión regular. Se podría mejorar.
Hay problemas con la precisión de la respuesta aceptada.
La función redonda (valor, decimales) en esta prueba funciona. a diferencia del ejemplo simple aFixed.
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 de mezcla
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);
}
}
}
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>
Utilicé estas respuestas relacionadas para ayudar con la implementación del filtro:
Puede formatear la moneda escribiendo su propio código, pero es solo una solución por el momento: cuando su aplicación crezca, puede necesitar otras monedas.
Hay otro problema con esto:
- Para EN-us - el signo dolar siempre está antes de la moneda - $ 2.00,
- Para PL seleccionado, devuelve signo después de cantidad como 2,00 zł.
Creo que la mejor opción es utilizar una solución compleja para la internacionalización, por ejemplo, la biblioteca vue-i18n ( http://kazupon.github.io/vue-i18n/ ).
Uso este plugin y no tengo que preocuparme por tales cosas. Por favor, mire la documentación - es muy simple:
http://kazupon.github.io/vue-i18n/guide/number.html
así que solo usas
<div id="app">
<p>{{ $n(100, ''currency'') }}</p>
</div>
y configurar EN-us para obtener $ 100.00 :
<div id="app">
<p>$100.00</p>
</div>
o establecer PL para obtener 100,00 PLN :
<div id="app">
<p>100,00 zł</p>
</div>
Este complemento también proporciona diferentes características como traducciones y formato de fecha.