Làm cách nào để định dạng tiền tệ trong thành phần Vue?


81

Thành phần Vue của tôi như thế này:

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

Kết quả của {{ item.total }}

26000000

Nhưng tôi muốn định dạng nó như thế này:

26.000.000,00

Trong jquery hoặc javascript, tôi có thể làm điều đó

Nhưng, làm thế nào để làm điều đó trong thành phần vue?


1
Nếu bạn có thể làm điều đó trong javascript, vì vậy bạn có thể làm điều đó trong Vue ... hãy sử dụng các thuộc tính được tính toán và trả về mã javascript.
Happyriri

Câu trả lời:


82

CẬP NHẬT: Tôi khuyên bạn nên sử dụng giải pháp có bộ lọc, do @Jess cung cấp.

Tôi sẽ viết một phương thức cho điều đó và sau đó khi bạn cần định dạng giá, bạn có thể chỉ cần đặt phương thức vào mẫu và chuyển giá trị xuống

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

Và sau đó trong mẫu:

<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 - Tôi không quá quan tâm đến việc thay thế và biểu thức chính quy. Nó có thể được cải thiện.enter code here


11
Xem thêm developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… để biết định dạng tiền tệ địa phương được tích hợp sẵn.
Roy J

@RoyJ Bắt tốt. Tôi vừa sao chép regex từ một dự án trước đó, về cơ bản anh ấy có thể trả về giá trị từ phương thức như anh ấy muốn.
Belmin Bedak

@BelminBedak bạn nghĩ gì về return (value/1).toFixed(2).toLocalString();?
retrovertigo

Hoạt động, nhưng thay thế tất cả các số thập phân bằng dấu phẩy
Dylan Glockler

Tại sao không sử dụng computedthay thế?
localhost

183

Tôi đã tạo một bộ lọc. Bộ lọc có thể được sử dụng trong bất kỳ trang nào.

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

Sau đó, tôi có thể sử dụng bộ lọc này như sau:

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

Tôi đã sử dụng các câu trả lời liên quan này để trợ giúp triển khai bộ lọc:


5
Người đàn ông của tôi! Tôi thậm chí không biết bạn có thể làm điều này. Cảm ơn đã giải quyết vấn đề tiền tệ của tôi và làm sạch các mixin của tôi vì hầu hết chúng đều làm những thứ này.
Ominus

1
đây là câu trả lời thích hợp
ierdna

Không Intlcó sự hỗ trợ tốt nhất .
Илья Зеленько

1
Làm thế nào về isNaN(parseFloat(value))thay vì typeof value !== "number"?
RonnyKnoxville

@JackalopeZero: Đúng, đó là một kiểm tra tốt hơn. Làm việc trong trường hợp của tôi.
dotNET

22

Với vuejs 2, bạn có thể sử dụng bộ lọc vue2 cũng có các tính năng khác.

npm install vue2-filters


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

Vue.use(Vue2Filters)

Sau đó sử dụng nó như vậy:

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

Tham khảo: https://www.npmjs.com/package/vue2-filters


10

Bạn có thể định dạng tiền tệ bằng cách viết mã của riêng mình nhưng đó chỉ là giải pháp cho thời điểm này - khi ứng dụng của bạn phát triển, bạn có thể cần các loại tiền tệ khác.

Có một vấn đề khác với điều này:

  1. Đối với EN-us - ký hiệu dolar luôn đứng trước tiền tệ - $ 2,00,
  2. Đối với PL đã chọn, bạn trả lại ký sau khi số tiền như 2,00 zł.

Tôi nghĩ lựa chọn tốt nhất là sử dụng giải pháp phức tạp để quốc tế hóa, ví dụ như thư viện vue-i18n ( http://kazupon.github.io/vue-i18n/ ).

Tôi sử dụng plugin này và tôi không phải lo lắng về những điều như vậy. Vui lòng xem tài liệu - nó thực sự đơn giản:

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

vì vậy bạn chỉ cần sử dụng:

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

và đặt EN-us để nhận $ 100.00 :

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

hoặc đặt PL để nhận 100,00 zł :

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

Plugin này cũng cung cấp các tính năng khác nhau như bản dịch và định dạng ngày.


8

Bình luận của @RoyJ có một gợi ý tuyệt vời. Trong mẫu, bạn chỉ có thể sử dụng các chuỗi bản địa hóa tích hợp sẵn:

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

Nó không được hỗ trợ trong một số trình duyệt cũ hơn, nhưng nếu bạn đang nhắm mục tiêu IE 11 trở lên, bạn sẽ ổn.


Đơn giản như thế này. Đã xác nhận là nó hoạt động. Cảm thấy như nó phải là câu trả lời được chọn!
UX Andre

4

Tôi đã sử dụng giải pháp bộ lọc tùy chỉnh do @Jess đề xuất nhưng trong dự án của tôi, chúng tôi đang sử dụng Vue cùng với TypeScript. Đây là cách nó trông như thế nào với TypeScript và các trình trang trí lớp:

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

Trong ví dụ này, bộ lọc chỉ có thể được sử dụng bên trong thành phần. Tôi vẫn chưa cố gắng triển khai nó như một bộ lọc chung.


2

Bạn có thể sử dụng ví dụ này

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

1

Có vấn đề với độ chính xác của câu trả lời được chấp nhận.

chức năng vòng (giá trị, số thập phân) trong thử nghiệm này hoạt động. không giống như ví dụ toFixed đơn giản.

đây là một thử nghiệm của phương pháp 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 />');

ví dụ về 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
bạn vẫn có thể sử dụng val.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".")sau đó cho. và, những thay đổi.
Artistan 19/07/17
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.