jonathanpmartins / v-money3

Vue3 currency input/directive mask
MIT License
103 stars 27 forks source link

Initial value problem #50

Closed diego-lipinski-de-castro closed 3 years ago

diego-lipinski-de-castro commented 3 years ago

Hi, I was testing this lib, and I see that if my I have the .lazy modifier, my input doesnt set the initial value of the v-model properly, when I remove the .lazy modifier, it inits correctly, is there any major problem of not having the .lazy modifier? the doc says it needs to exist for the binding to work properly, thats not really useful information tho

diego-lipinski-de-castro commented 3 years ago

Yeah I see, without the .lazy modifier, the input actually appears to work as intended, however, while the input is showing R$ 1.000.000,00, the actual v-model value is R$ 100.000,000, so thats fucked

jonathanpmartins commented 3 years ago

Can you give me CodeSandbox example? Perhaps some example of your setup. I assume you are working with directives right? What version of Vue and V-Money3 are you using? Access to a repository where the problem exists is good too... Or a video with a step by step to get to the problem.

diego-lipinski-de-castro commented 3 years ago

Yes I am working with directives, the versions are as following:

"vue": "^3.0.5", "v-money3": "^3.20.0"

I dont think it is a problem with the library itself. It is already expected to have weird behavior when .lazy is not used. To reproduce this "weird behavior" you just need to remove the .lazy, print the result on the screen, erase everything in the input field and start typing.

https://user-images.githubusercontent.com/29608698/136311391-9fe4a6d7-6763-4fd2-a053-a7f6d484a25b.mov

The problem was that my input was wrapped inside a div with v-if condition. When you have that, you cant use the .lazy modifier because the initial value of the input will be 0 instead of the expected value, probably because the input is not in the dom. If you remove the .lazy modifier, when that condition change to true, and the input gets rendered, the value will be set as expected.

I solved this by instead of doing a v-if, I do a v-show, so the input is rendered from the start but just hidden

diego-lipinski-de-castro commented 3 years ago

I actually tried to reproduce my specific problem in the sandbox however I was not able to, maybe it was something else inside my component that was bugging the input. I think its worth mentioning I am using the lib inside laravel inertia tho

diego-lipinski-de-castro commented 3 years ago

This is my input btw, very basic, its funny, inside my project, with the .lazy modifier, the initial value is still always 0, so I cant use it, cant reproduce outside tho

<div class="mt-1">
    <input
      v-money3="{
        prefix: 'R$ ',
        suffix: '',
        thousands: '.',
        decimal: ',',
        precision: 2,
        disableNegative: false,
        disabled: false,
        min: null,
        max: null,
        allowBlank: false,
        minimumNumberOfCharacters: 0,
      }"
      v-model.lazy="selectedUnit.price"
      id="unit-price"
      type="text"
      class="
        block
        w-full
        shadow-sm
        sm:text-sm
        focus:ring-rauzee-light-500
        focus:border-rauzee-light-500
        border-gray-300
        rounded-md
      "
    />
  </div>
jonathanpmartins commented 3 years ago

Directives only work with v-model.lazy. From Readme.md on directives:

Must use v-model.lazy to bind works properly.

I strongly recommend you to use the component instead of the directive. Something like this should work fine.

<template>
  <money3
    id="unit-price"
    v-model="amount"
    v-bind="{
      prefix: 'R$ ',
      suffix: '',
      thousands: '.',
      decimal: ',',
      precision: 2,
      disableNegative: false,
      disabled: false,
      min: null,
      max: null,
      allowBlank: false,
      minimumNumberOfCharacters: 0,
    }"
    class="
      block
      w-full
      shadow-sm
      sm:text-sm
      focus:ring-rauzee-light-500
      focus:border-rauzee-light-500
      border-gray-300
      rounded-md
    "
  />
</template>

<script>
  import { Money3Component } from 'v-money3'

  export default {
    components: { money3: Money3Component },
    data () {
      return {
        amount: 12345.67,
      }
    }
  }
</script>
jonathanpmartins commented 3 years ago

"vue": "^3.0.5", "v-money3": "^3.20.0"

You should be getting a warning on installation. Since version 3.17.6 of v-money3, the project has a peerDependency on Vue 3.2+.

I recommend you to upgrade to the last Vue version 3.2.19