Reputation: 15848
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
Upvotes: 2
Views: 9157
Reputation: 135772
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>
<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()
.
Upvotes: 4
Reputation: 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.
Upvotes: -1