'Using a method with v-model in vue

I have a question about using vue's v-model with a method instead of computed. I know we can't exactly do that based on what I see here: How to bind a v-model with a method in Vue.js. But I know it has a work around. I'm using bootstrap vue's datepicker but I think the concept is not constrained by this.

I have two datepickers:

<b-form-datepicker id="end-datepicker" v-model="formatISO8601Start" class="mb-2 border-0" hide-header></b-form-datepicker>
<b-form-datepicker id="end-datepicker" v-model="formatISO8601End" class="mb-2 border-0" hide-header></b-form-datepicker>

If I only have one date picker then I would just have a computed, like below:

formatISO8601: {
      get: function() {
          return .....
      },
      set: function(dateSegment) {
          ....
          ....
      }
    },

problem is I don't believe I can use the same computed for the two datepickers' v-models as they would reference the same thing. I can of course created two computed, one for each datepicker but I think that is bad practice since I'm duplicating code.

So I thought maybe I can use two methods instead, and instead of using a

v-model="formatISO8601"

, I can replace it with:

:value="getISO8601Time('start')" @input="setISO8601Time(????)"

That way I can use what is passed as the parameter to control the logic:

<b-form-datepicker id="end-datepicker" :value="getISO8601Time('start')" @input="setISO8601Time(????)" class="mb-2 border-0" hide-header></b-form-datepicker>
<b-form-datepicker id="end-datepicker" :value="getISO8601Time('end')" @input="setISO8601Time(????)" class="mb-2 border-0" hide-header></b-form-datepicker>

getISO8601Time(time) {
  return ......
}

setISO8601Time(????) {
  ....
  ....
}

This is where I am confused. Note where I have put the ????. In computed, the parameter in set, ie dateSegment auto populates the date selected, however in a method this does not happen. How do I get the date selected in this case?



Solution 1:[1]

Maybe you can try with data function:

new Vue({
  el: "#demo",
  data() {
    return {
      start: null, 
      end: null
    }
  },
  methods: {
    setISO8601Time(e, time) {
      e = new Date(e)
      this[time] = e.toISOString()
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.css" />
<script src="https://unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.js"></script>
<script src="https://unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue-icons.min.js"></script>
<div id="demo">
  <b-form-datepicker id="end-datepicker" 
    :value="start" 
    @input="setISO8601Time($event, 'start')" 
    class="mb-2 border-0" hide-header>
  </b-form-datepicker>
  {{ start }}
  <b-form-datepicker id="end-datepicker" 
    :value="end" 
    @input="setISO8601Time($event, 'end')" 
    class="mb-2 border-0" hide-header>
  </b-form-datepicker>
  {{  end }}
</div>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1