vue-i18n как сократить отображение валюты? - PullRequest
0 голосов
/ 11 июня 2018

Есть ли способ достичь того, что d3 может сделать с precisionPrefix в экосистеме vue-i18n?

Существует открытый вопрос здесь .

И я нашел старую проблему для Intl объекта здесь .

Спасибо за вашу помощь.

1 Ответ

0 голосов
/ 16 июня 2018

Один хакерский способ будет заменен VueI18n.n на ваш собственный обработчик.

  1. добавьте пользовательское свойство = сокращенно до VueI18n.numberFormats, чтобы определить, применимо лиспециальный стиль.

  2. сохранить оригинал VueI18n.n в VueI18n.n1 (мы все еще будем использовать VueI18n.n1 для других стилей)

  3. использует вашсобственный обработчик для замены VueI18n.n, затем внутри обработчика проверьте, является ли numberFormatter.abbreviate истиной, , если да , примените свой особый стиль (в демонстрационной части ниже просто используется выражение regex для его реализации).

Как показано ниже простая демонстрация:

PS: ниже я использую одно простое регулярное выражение для применениястили, для какого-то специального числового формата он может не работать, вам нужно улучшить его самостоятельно.

Vue.use(VueI18n)

const numberFormats = {
   'en-US': {
     currency: {
       style: 'currency', currency: 'USD', currencyDisplay: 'symbol', useGrouping: false
     }
   },
   'ja-JP': {
     currency: {
       style: 'currency', currency: 'JPY', currencyDisplay: 'name', 
abbreviate: true, // custom property to determinate whether apply special styles
       maximumSignificantDigits: 4, useGrouping: true
     }
   }
 }

const i18n = new VueI18n({
  numberFormats
})

i18n.n1 = i18n.n // save default i18n.n to i18n.n1

i18n.n= function (nValue, nStyle) {
  let numberFormatter = this.getNumberFormat(this.locale) // get NumberFormat Based on locale
  if (numberFormatter[nStyle].abbreviate) { // if custom property is true
    let newValue = Math.round(nValue/1000000) // divide 10^6 for millions, divide 10^3 for K .etc
    return this.n1(newValue, nStyle).replace(/(\d[\d|,]*)(\.\d+)?/, '$1 $2M')
  }
  return this.n1(nValue, nStyle) // for others , use default i18n.n to process.
}

Vue.config.productionTip = false

app = new Vue({
  el: "#app",
  i18n,
  data: {
    test: 1234567890,
    language: 'en-US'
  },
  computed: {
    computedTest: function () {
      return this.$n(this.test, 'currency')
    }
  },
  methods: {
    toggleLanguage: function () {
      this.language = this.language === 'en-US' ? 'ja-JP' : 'en-US'
      this.$i18n.locale = this.language
    }
  }
})
<script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-i18n/7.8.0/vue-i18n.js"></script>
<div id="app">
  <button @click="toggleLanguage()">Language </button>
  <p>Language: [{{language}}]</p>
  <p>Org: {{test}}</p>
  <p>localed: {{computedTest}}</p>
</div>

Редактировать: другой подход: использует D3-формат

Vue.use(VueI18n)

const numberFormats = {
   'en-US': {
     currency: {
       style: 'currency', currency: 'USD', currencyDisplay: 'symbol', useGrouping: false
     }
   },
   'ja-JP': {
     currency: {
       style: 'currency', currency: 'JPY', currencyDisplay: 'name', 
abbreviate: true, // custom property to determinate whether apply special styles
       maximumSignificantDigits: 4, useGrouping: true
     }
   }
 }

const i18n = new VueI18n({
  numberFormats
})

let d3Locales = {}

axios.get('https://unpkg.com/d3-format@1/locale/ja-JP.json')
.then(function (response) {
  d3Locales['ja-JP'] = response.data
})
.catch(function (error) {
  console.log(error);
});

axios.get('https://unpkg.com/d3-format@1/locale/en-US.json')
.then(function (response) {
  d3Locales['en-US'] = response.data
})
.catch(function (error) {
  console.log(error);
});

i18n.n1 = i18n.n // save default i18n.n to i18n.n1

i18n.n= function (nValue, nStyle) {
  let numberFormatter = this.getNumberFormat(this.locale) // get NumberFormat Based on locale
  if (numberFormatter[nStyle].abbreviate) { // if custom property is true
    d3.formatDefaultLocale(d3Locales[this.locale])
    let p = d3.precisionPrefix(1e4, 1e6),
        f = d3.formatPrefix("$." + p, 1e6)
    return f(nValue);
  }
  return this.n1(nValue, nStyle) // for others , use default i18n.n to process.
}

Vue.config.productionTip = false

app = new Vue({
  el: "#app",
  i18n,
  data: {
    test: 1234567890,
    language: 'en-US'
  },
  computed: {
    computedTest: function () {
      return this.$n(this.test, 'currency')
    }
  },
  methods: {
    toggleLanguage: function () {
      this.language = this.language === 'en-US' ? 'ja-JP' : 'en-US'
      this.$i18n.locale = this.language
    }
  }
})
<script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-i18n/7.8.0/vue-i18n.js"></script>
<script src="https://d3js.org/d3-format.v1.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<div id="app">
  <button @click="toggleLanguage()">Language </button>
  <p>Language: [{{language}}]</p>
  <p>Org: {{test}}</p>
  <p>localed: {{computedTest}}</p>
</div>
...