Vue 구성 요소에서 통화 형식을 어떻게 지정합니까?


85

내 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 구성 요소에서 어떻게 수행합니까?


1
Vue에서 할 수 있도록 자바 스크립트로 할 수 있다면 ... 계산 된 속성을 사용하고 자바 스크립트 코드를 반환하세요.
Happyriri

답변:


83

업데이트 : @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>

BTW-대체 및 정규 표현식에 너무 신경 쓰지 않았습니다. 개선 될 수 있습니다.enter code here


12
내장 된 현지화 통화 형식 은 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… 를 참조하십시오 .
Roy J

@RoyJ Good catch. 방금 이전 프로젝트에서 정규식을 복사했는데 기본적으로 원하는대로 메서드에서 값을 반환 할 수 있습니다.
Belmin Bedak 2017

@BelminBedak 어떻게 생각 return (value/1).toFixed(2).toLocalString();하십니까?
retrovertigo

작동하지만 모든 소수점을 쉼표로 대체
Dylan Glockler

computed대신 사용 하지 않으시겠습니까?
localhost

191

필터를 만들었습니다. 필터는 모든 페이지에서 사용할 수 있습니다.

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

그런 다음이 필터를 다음과 같이 사용할 수 있습니다.

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

필터 구현을 돕기 위해 다음과 같은 관련 답변을 사용했습니다.


5
내 남자! 나는 당신이 이것을 할 수 있다는 것을 몰랐습니다. 고맙게도 내 통화 문제를 해결하고 대부분이 이런 종류의 일을하고 있었기 때문에 내 믹스 인을 정리했습니다.
Ominus

2
이 적절한 대답이다
ierdna

Intl하지 최선가 지원 .
Илья Зеленько apr

1
어떻게 약 isNaN(parseFloat(value))이 아니라 typeof value !== "number"?
RonnyKnoxville

1
때로는 데이터베이스가 문자열을 반환하기 때문에 조건부 부분을 변경할 것입니다. 아마도 해당 조건부에서 문자열을 숫자로 캐스팅하는 것이 더 좋을 것입니다.
Andres Felipe

22

vuejs 2에서는 다른 장점도있는 vue2-filter를 사용할 수 있습니다.

npm install vue2-filters


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

Vue.use(Vue2Filters)

그런 다음 다음과 같이 사용하십시오.

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

참고 : https://www.npmjs.com/package/vue2-filters


11

고유 한 코드를 작성하는 통화의 형식을 지정할 수 있지만 현재로서는 그저 해결책 일뿐입니다. 앱이 커질 때 다른 통화가 필요할 수 있습니다.

이것에 또 다른 문제가 있습니다.

  1. EN-us의 경우-달러 기호는 항상 통화보다 앞에 있습니다-$ 2.00,
  2. 선택한 PL의 경우 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>$100.00</p>
</div>

또는 PL을 설정하여 100,00 zł 를 얻습니다 .

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

이 플러그인은 번역 및 날짜 형식과 같은 다양한 기능도 제공합니다.


8

@RoyJ의 의견에는 큰 제안이 있습니다. 템플릿에서 내장 된 현지화 된 문자열을 사용할 수 있습니다.

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

일부 구형 브라우저에서는 지원되지 않지만 IE 11 이상을 대상으로하는 경우 괜찮습니다.


이렇게 간단합니다. 작동하는지 확인했습니다. 정답이 될 것 같은 느낌!
UX Andre

5

@Jess가 제안한 사용자 지정 필터 솔루션을 사용했지만 프로젝트에서는 TypeScript와 함께 Vue를 사용하고 있습니다. 이것은 TypeScript 및 클래스 데코레이터의 모습입니다.

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

이 예에서 필터는 구성 요소 내에서만 사용할 수 있습니다. 아직 전역 필터로 구현하려고 시도하지 않았습니다.


2

이 예를 사용할 수 있습니다.

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

1

수락 된 답변의 정확성에 문제가 있습니다.

이 테스트의 round (value, decimals) 함수가 작동합니다. 간단한 toFixed 예제와는 다릅니다.

이것은 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 />');

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
그 후에도 여전히 val.toString().replace(/\B(?=(\d{3})+(?!\d))/g, "."). 및, 변경.
Artistan 17
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.