Vue.js: How to format a value in a v-model?

Asked

Viewed 2,045 times

1

I have the following problem, I need to format an input value, directly when the user is filling the field (@keypress or @input).

When I use the method to format outside the input it works, but if I try to use it with the v-model I believe it conflicts the values.

What would be an alternative to this question?

That is the method:

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

That is the call:

    {{ formatPrice(valorPrecoImovel) }}
      <input class="ipt-precoimovel" type="text" v-model="valorPrecoImovel" v-on:keypress="isNumber($event); formatPrice;" id="precoImovel">

I can’t call the method inside the v-model, for example:

v-model="formatPrice(valorPrecoImovel)"
  • Do you want to format the value inside the input or just the one inside the template {{ }}?

  • the value within the input

2 answers

3


What you want to do has some complexity because you combine the v-model with the formatting of the input value the user is entering.

You can do it using a value computed and using setters and getters to have more control over its value. Combining this with an internal variable/property meu_valor you can do what you want.

There is an untreated aspect (which I believe is outside the scope of the question) that is the positioning of the cursor when writing.

A suggestion from the first part (which you describe in the question) would be:

new Vue({
  el: "#app",
  data: {
    meu_valor: '0,00'
  },
  computed: {
    valorPrecoImovel: {
      // getter
      get: function() {
        return this.meu_valor;
      },
      // setter
      set: function(newValue) {
        this.meu_valor = this.formatPrice(newValue);
      }
    }
  },
  methods: {
    formatPrice(value) {
      const val = Number(value.replace(",", "."));
      if (!val) return '0,00';
      const valueString = val.toFixed(2).replace(".", ",");
      return valueString.replace(/\B(?=(\d{3})+(?!\d))/g, ".");
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.min.js"></script>

<div id="app">
  <input class="ipt-precoimovel" type="text" v-model="valorPrecoImovel" ref="precoImovel" id="precoImovel">
</div>

3

v-model is for attribution only. You won’t be able to format the results the way you called them v-model="formatPrice(valorPrecoImovel)" because it is not an expression of attribution.

What I suggest to you is to leave the v-model free to set the values and format it through a callback on @input.

window.addEventListener('load', function () {
  
  new Vue({
   el: "#app",
   data: {
       meu_valor: 0
   },
   methods: {
    somenteNumeros: function (valor) {
      return (valor + '').replace(/\D+/g, '');
    }
   }
  })
  
})
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.min.js"></script>

<div id="app">
    
<input type="text" @input="meu_valor = somenteNumeros(meu_valor)" v-model="meu_valor">

{{ meu_valor }}
</div>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.