如何在 Vue 组件中格式化货币?
How do I format currencies in a Vue component?
我的 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组件中如何实现呢?
UPDATE: I suggest using a solution with filters, provided by @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, ',');
});
@RoyJ 的评论提出了很好的建议。在模板中,您可以只使用内置的本地化字符串:
<small>
Total: <b>{{ item.total.toLocaleString() }}</b>
</small>
它在某些较旧的浏览器中不受支持,但如果您的目标是 IE 11 及更高版本,则应该没问题。
已接受答案的准确性存在问题。
此测试中的 round(value, decimals) 函数有效。
与简单的 toFixed 示例不同。
这是对 toFixed 与 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 />');
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);
}
}
}
您可以编写自己的代码来格式化货币,但这只是目前的解决方案 - 当您的应用增长时,您可能需要其他货币。
这里还有一个问题:
- 对于 EN-us - 美元符号始终在货币之前 - $2.00,
- 对于选定的 PL,您 return 在 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>0.00</p>
</div>
或设置 PL 以获得 100,00 zł:
<div id="app">
<p>100,00 zł</p>
</div>
此插件还提供不同的功能,如翻译和日期格式。
我创建了一个过滤器。过滤器可用于任何页面。
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>
我使用这些相关答案来帮助实施过滤器:
- How to format numbers as currency strings
- Check whether variable is number or string in JavaScript
对于 vuejs 2,您可以使用 vue2-filters,它还有其他优点。
npm install vue2-filters
import Vue from 'vue'
import Vue2Filters from 'vue2-filters'
Vue.use(Vue2Filters)
然后像这样使用它:
{{ amount | currency }} // 12345 => ,345.00
我使用了@Jess 提出的自定义过滤器解决方案,但在我的项目中,我们将 Vue 与 TypeScript 结合使用。
这是使用 TypeScript 和 class 装饰器的样子:
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);
}
}
在此示例中,过滤器只能在组件内部使用。我还没有尝试将其实现为全局过滤器。
你可以使用这个例子
formatPrice(value) {
return value.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, ',');
},
试试这个:
methods: {
formatPrice(value) {
var formatter = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'PHP',
minimumFractionDigits: 2
});
return formatter.format(value);
},
}
那么你可以这样称呼它:
{{ formatPrice(item.total) }}
numeral.js 是一个 JavaScript 用于格式化和操作数字的库。
您可以使用它轻松格式化货币。
例如,
// price = 1200
{numeral(price).format(`[=10=],0.00`)}
// result ,200.00
这是文档。 http://numeraljs.com/
我的 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组件中如何实现呢?
UPDATE: I suggest using a solution with filters, provided by @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, ',');
});
@RoyJ 的评论提出了很好的建议。在模板中,您可以只使用内置的本地化字符串:
<small>
Total: <b>{{ item.total.toLocaleString() }}</b>
</small>
它在某些较旧的浏览器中不受支持,但如果您的目标是 IE 11 及更高版本,则应该没问题。
已接受答案的准确性存在问题。
此测试中的 round(value, decimals) 函数有效。 与简单的 toFixed 示例不同。
这是对 toFixed 与 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 />');
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);
}
}
}
您可以编写自己的代码来格式化货币,但这只是目前的解决方案 - 当您的应用增长时,您可能需要其他货币。
这里还有一个问题:
- 对于 EN-us - 美元符号始终在货币之前 - $2.00,
- 对于选定的 PL,您 return 在 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>0.00</p>
</div>
或设置 PL 以获得 100,00 zł:
<div id="app">
<p>100,00 zł</p>
</div>
此插件还提供不同的功能,如翻译和日期格式。
我创建了一个过滤器。过滤器可用于任何页面。
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>
我使用这些相关答案来帮助实施过滤器:
- How to format numbers as currency strings
- Check whether variable is number or string in JavaScript
对于 vuejs 2,您可以使用 vue2-filters,它还有其他优点。
npm install vue2-filters
import Vue from 'vue'
import Vue2Filters from 'vue2-filters'
Vue.use(Vue2Filters)
然后像这样使用它:
{{ amount | currency }} // 12345 => ,345.00
我使用了@Jess 提出的自定义过滤器解决方案,但在我的项目中,我们将 Vue 与 TypeScript 结合使用。 这是使用 TypeScript 和 class 装饰器的样子:
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);
}
}
在此示例中,过滤器只能在组件内部使用。我还没有尝试将其实现为全局过滤器。
你可以使用这个例子
formatPrice(value) {
return value.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, ',');
},
试试这个:
methods: {
formatPrice(value) {
var formatter = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'PHP',
minimumFractionDigits: 2
});
return formatter.format(value);
},
}
那么你可以这样称呼它:
{{ formatPrice(item.total) }}
numeral.js 是一个 JavaScript 用于格式化和操作数字的库。
您可以使用它轻松格式化货币。
例如,
// price = 1200
{numeral(price).format(`[=10=],0.00`)}
// result ,200.00
这是文档。 http://numeraljs.com/