0

I am trying to use iMask.js to change 'yyyy-mm-dd' to 'dd/mm/yyyy' with my component however when I am setting the value I think it is taking the value before the iMask has finished. I think using maskee.updateValue() would work but don't know how to access maskee from my component.

I am also not sure if I should be using a directive to do this.

Vue.component("inputx", {
  template: `
  <div>
  <input v-mask="" v-model="comp_date"></input>
  </div>
    `,
  props: {
    value: { type: String }
  },
  computed: {
    comp_date: {
      get: function () {
        return this.value.split("-").reverse().join("/");
      },
      set: function (val) {
        const iso = val.split("/").reverse().join("-");            
        this.$emit("input", iso);
      }
    }
  },
  directives: {
    mask: {
      bind(el, binding) {
        var maskee = IMask(el, {
          mask: "00/00/0000",
          overwrite: true,
        });
      }
    }
  }
});

var app = new Vue({
  el: "#app",
  data: {
    date: "2020-12-30"
  }
});
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script src="https://unpkg.com/imask"></script>

<div id="app">
    <inputx v-model="date"></inputx>    
    Date: {{date}}
</div>

1 Answer 1

1

The easiest way you can achieve this is by installing the external functionality on the mounted hook of your Vue component, instead of using a directive.

In this way you can store the 'maskee' object on your component's data object to later access it from the setter method.

Inside the setter method you can then call the 'updateValue' method as you hinted. Then, you can extract the processed value just by accessing the '_value' prop of the 'maskee' object.

Here is a working example:

 Vue.component("inputx", {
template: `
<div>
<input ref="input" v-model="comp_date"></input>
</div>
  `,
data: {
  maskee: false,
},
props: {
  value: { type: String },
},
computed: {
  comp_date: {
    get: function () {
      return this.value.split("-").reverse().join("/");
    },
    set: function () {
      this.maskee.updateValue()
      const iso = this.maskee._value.split("/").reverse().join("-");            
      this.$emit("input", iso);
    }
  }
},
mounted(){
  console.log('mounted');
  const el = this.$refs.input;

  this.maskee = IMask(el, {
    mask: "00/00/0000",
    overwrite: true,
  });
  console.log('maskee created');
}
  });

var app = new Vue({
  el: "#app",
  data: {
    date: "2020-12-30"
  }
});
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script src="https://unpkg.com/imask"></script>

<div id="app">
    <inputx v-model="date"></inputx>    
    Date: {{date}}
</div>

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

2 Comments

looks like this.maskee.updateValue() messes with the cursor so I changed the set function to setTimeout(() => { const iso = this.maskee.value.split("/").reverse().join("-");this.$emit("input", iso); },0); and it worked!
@Soth Glad it worked with that workaround!

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.