duplicated operator(or attribute) on the same input control - v-model and @change I wrote a code like below - It is nuxt.js, which is one of the Vue frameworks. This code will be expected to


When change event triggered, update data value. There would be some logic to alter passed data
At the same time, it connected with data value to apply input box changing




&lt;template&gt;
  &lt;div&gt;
    &lt;!-- I got question here --&gt;
    &lt;input type="text" ref="receiver" @change="applyData('receiver')" v-model="deliveryInfo.receiver" /&gt;
    &lt;button type="button" @click="test"&gt;TEST&lt;/button&gt;
  &lt;/div&gt;
&lt;/template&gt;
&lt;script&gt;
  export default {
    data: function () {
      return {
        deliveryInfo: {
          receiver: ''
        }
      }
    },
    methods: {
      applyData: function (refName) {
        let ref = this.$refs[refName];
        if (ref) {
          let temp = {};
          temp[refName] = ref.value;
          this.applyAddress(temp);
        } else {
          console.log("There is no " + refName + " in this.$refs");
        }
      },
      applyAddress: function (options) {
        this.deliveryInfo = Object.assign({}, this.deliveryInfo, options);
        this.$emit('applyChildData', this.deliveryInfo);
      },

      test: function () {
          console.log('set John Doe');
        this.deliveryInfo = Object.assign({}, this.deliveryInfo, {receiver: 'John Doe'});
        console.log('After change ', this.deliveryInfo);
        // It triggers applyData method and change input element value
        // But when I remove v-model in input value, it is not working
      }
    }
  }
&lt;/script&gt;




And it works as expected.

However, using v-model and @change at the same tag looks weird to me since both of tag manipulates the connected value(in this case, it would be deliveryInfo.receiver)

Is this code OK to use in production project?
Thanks!

FYI, in my real case, it applied to a phone number. I want to show a phone number without dashes in a browser, but data should be saved with dashes.

So when people type in the input, @change alter data to insert dashes.
Responding to Your question

This is good use of ref and Object.assign() but normally this would be a good place to use a watched Property, or if you need to add dashes, a computed property.

Take a look at the example below, which uses a watcher, instead of the @onchange, which means that the method applyData() can be eliminated:



const form = new Vue({
    el: '#form',
    data: function () {
      return {
        deliveryInfo: {
          receiver: ''
        }
      }
    },
    watch: {
      'deliveryInfo.receiver': function(newValue, oldValue) {
        console.log('receiver changed - deliveryinfo:', this.deliveryInfo);
        this.$emit('applyChildData', this.deliveryInfo);
      }
    },
    methods: {
      test: function () {
          console.log('set John Doe');
        this.deliveryInfo = Object.assign({}, this.deliveryInfo, {receiver: 'John Doe'});
        console.log('After change ', this.deliveryInfo);
        // It triggers applyData method and change input element value
        // But when I remove v-model in input value, it is not working
      }
    }
  });
&lt;script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"&gt;&lt;/script&gt;

  &lt;div id="form"&gt;
    &lt;!-- I got question here --&gt;
    &lt;input type="text" ref="receiver" v-model="deliveryInfo.receiver" /&gt;&lt;!--@change="applyData('receiver')"--&gt;
    &lt;button type="button" @click="test"&gt;TEST&lt;/button&gt;
  &lt;/div&gt;




Or the snippet below which uses a computed property to add a dash between the third and fourth characters...



const form = new Vue({
    el: '#form',
    data: function () {
      return {
        deliveryInfo: {
          receiver: ''
        }
      }
    },
    computed: {
      dashedReceiver: function() {
        if (this.deliveryInfo.receiver.length &gt; 3) {
          return this.deliveryInfo.receiver.slice(0,3) + '-' + this.deliveryInfo.receiver.slice(3);
        }
        return this.deliveryInfo.receiver;
      }
    }
  });
&lt;script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"&gt;&lt;/script&gt;

  &lt;div id="form"&gt;
    &lt;!-- I got question here --&gt;
    &lt;input type="text" ref="receiver" v-model="deliveryInfo.receiver" /&gt;
    &lt;div&gt;{{dashedReceiver}}&lt;/div&gt;
  &lt;/div&gt;




Other feedback

One other critique I have is this line:


let ref = this.$refs[refName];



That variable never gets re-assigned so to avoid accidental re-assignment, use const instead of let. There are some who recommend the following:


  
  use const by default
  only use let if rebinding is needed
  1
  


There may not be much of a performance difference here although after reading some SO answers like this one and this one there is a potential but that might only be if a primitive type value (e.g. 42) was used.

1https://mathiasbynens.be/notes/es6-const