2

Let's figure a simple sum app. two inputs, a and b and a c result.

we have this markup

<div id="app">
<input v-model.number="v1">
<input v-model.number="v2">
{{v3}}
</div>

and this Vue script

var vm = new Vue ({
    el: "#app",
       data: {
        a:0,
        b:0,
    },        
    computed: {
     c:function(){
            return this.a + this.b; 
        }
    }
})

this works great except that I'm working with localized numbers. that means. using comma "," instead of dot "." and dot instead of comma .

entering number with decimal places confuses vue, and it are not able to make a correct sum.

What can I do in order to make VueJS understand localized number input and them make the correct sum?

for instance in pt-BR locale: 1.000,30 + 100,30 = 1.100,60

2 Answers 2

4

Well, first of all, a number is just a number. Internally, the . will always be the decimal separator.

So a number like 1.100,60 is the number 1100.60 just printed in a different locale.

To print it, just use JavaScript's Number#toStringLocale():

var vm = new Vue({
  el: "#app",
  data: {
    a: 1110.12,
    b: 10000.11,
  },
  computed: {
    c: function() {
      return this.a + this.b;
    }
  }
})
<script src="https://unpkg.com/vue@2"></script>

<div id="app">
  <input v-model.number="a">
  <input v-model.number="b">
  <hr>
  Browser's locale: {{c.toLocaleString()}}<br>
  en-US locale: {{c.toLocaleString('en-US')}}<br>
  pt-BR locale: {{c.toLocaleString('pt-BR')}}<br>
</div>

Using a formatted <input>

Now, if you want the <input> to take localized numbers, that is not a problem specific to Vue, but to JavaScript and the browser in general. This means that you'll have to find a custom component that implements the behavior you want (formatting in the <input>).

Luckily, a quick search brings one that seems to to the job:

Vue.use(VueNumeric.default)
var vm = new Vue({
  el: "#app",
  data: {
    a: 1110.12,
    b: 10000.11,
  },
  computed: {
    c: function() {
      return this.a + this.b;
    }
  }
})
<script src="https://unpkg.com/accounting-js"></script>
<script src="https://unpkg.com/vue@2"></script>
<script src="https://unpkg.com/vue-numeric"></script>

<div id="app">
  Formatted inputs:
  <vue-numeric currency="R$" separator="," precision="2" v-model="a"></vue-numeric>
  <vue-numeric currency="$" separator="." precision="2" v-model="b"></vue-numeric>
  <hr>
  Browser's locale: {{c.toLocaleString()}}<br>
  en-US locale: {{c.toLocaleString('en-US')}}<br>
  pt-BR locale: {{c.toLocaleString('pt-BR')}}<br>
</div>

Again, the component just changes the input field. The number will still be just a number and the "printing" will still have to be done using .toLocaleString().

Sign up to request clarification or add additional context in comments.

1 Comment

vue-numeric looks promising, but doesn't seem to support Vue 3 and TypeScript, unfortunately.
-1

Using vuex as store my approach on doing this was to use two-way-computed-property with a getter and a setter.

The getter takes the data (in float) out of the store and shows it in the input-field formated with .toLocalString().

The setter takes the input as a local-formatted string and replaces ( .replace() ) the dots with "" and the commas with "."- after doing this string needs to be parsed as float ( parseFloat(string) ) and then the action for updating the store will be dispatched.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.