bootstrap-datepicker bound to vue v-model reverts

2019-08-23 17:53发布

I have a form where a datepicker follows a text input. After the text input has been given, the datepicker receives a date from an ajax call. The focus is now on the datepicker, which shows (as expected) the received date. When the user tabs to the next input, the datepicker reverts to its previous data, which ends up being the placeholder in most cases.

The vue app code:

var app = new Vue({
  el: "#app",
  data: {
    theDate: '',
    aNumber: 0,
    bNumber: 0
  },
  mounted() {
    $("#aDate").datepicker({
      format: 'dd/mm/yyyy'
    });
    $("#aDate").datepicker().on(
      "changeDate", () => {
        this.theDate = $('#aDate').val()
      }
    );

  },
  methods: {
    check() {
      console.log('theDate: ' + this.theDate + ', aNumber: ' + this.aNumber + ', bNumber: ' + this.bNumber);
    },
    setDate() {
        this.theDate = '18/12/2018';
    }
  }
})

And the html:

<body>
  <div id="app">
    <input type="text" id="bNumber" v-model="bNumber" /><br>
    <input type="text" id="aDate" placeholder="mm/dd/yyyy" v-model="theDate" /><br>
    <input type="text" id="aNumber" v-model="aNumber" /><br>
    <button type="button" @click="check">Check</button>
    <button type="button" @click="setDate">Set Date</button>
  </div>
</body>

This can be observed in this fiddle if following these steps

  1. Enter any number in the top input
  2. Then tab to the datepicker input
  3. Click the "Set Date" button (simulating received data)
  4. Then focus on the datepicker input again by clicking in it
  5. Now tab out to the next input
  6. The date in the datepicker has reverted to the previous value

How can this be prevented and the data be made persistent?

I have tried the solution from this question but the behaviour is the same.

1条回答
聊天终结者
2楼-- · 2019-08-23 18:21

The problem is the actual date value being controlled by the datepicker, in which case there's no point in using v-model. So much that setting the theDate to any value does not really affect anything. This is understandable since you are using Bootstrap which has a jQuery dependency. I would recommend Vue-flatpickr as an alternative. But if you need to stick with this, here's a possible fix:

I've removed unnecessary attributes for brevity:

<input type="text" ref="datepicker" placeholder="mm/dd/yyyy" />

var app = new Vue({
  el: "#app",
  data: {
    theDate: '',
    aNumber: 0,
    bNumber: 0
  },
  mounted() {
    $(this.$refs.datepicker).datepicker({
      format: 'dd/mm/yyyy'
    })
    .on("changeDate", e => {
      this.update(e.target.value);
    });
  },
  methods: {
    check() {
      console.log('theDate: ' + this.theDate + ', aNumber: ' + this.aNumber + ', bNumber: ' + this.bNumber);
    },
    setDate() {
      this.update('18/12/2018');
    },
    update(value) {
      $(this.$refs.datepicker).datepicker("update", value);
    }
  }
})

Basically, you need to update the date with the provided API.

查看更多
登录 后发表回答