Vue bootstrap b-form-select устанавливает значение $ anyDirty для vuelidate в true при загрузке

#javascript #vue.js #vuelidate

#javascript #vue.js #vuelidate

Вопрос:

Проблема, с которой я сталкиваюсь, связана с input событием, которое запускается, когда я впервые устанавливаю значение в v-model , эти данные загружаются через API; Я понимаю, почему для формы устанавливается значение dirty (поскольку это изменяется), но это вызывает проблемы в другом компоненте, который у меня есть, который проверяет, установлен ли для $v.$anyDirty флага значение true, и если это так, создает всплывающее окно с надписью «вы уверены, что хотите перейти», но вызывая $v.reset() после загрузки данных не работает.

 Vue.use(vuelidate.default);
const { required } = window.validators;
new Vue({
  el: "#app",
  data: {
    todos: [],
    todo: ""
  },
  async created() {
    var data = await axios.get("https://jsonplaceholder.typicode.com/todos");
    this.todos = data.data.map(d => d.id);
    this.todo = this.todos[0];
    this.$v.$reset()
  },
  validations() {
    return {
      todo: { required }
    };
  }
});  
 <link href="https://unpkg.com/bootstrap-vue@2.0.0-rc.11/dist/bootstrap-vue.css" rel="stylesheet"/>
<link href="https://unpkg.com/bootstrap@4.1.3/dist/css/bootstrap.min.css" rel="stylesheet"/>

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/bootstrap-vue@2.0.0-rc.11/dist/bootstrap-vue.min.js"></script>
<script src="https://unpkg.com/vuelidate@0.7.4/dist/validators.min.js"></script>
<script src="https://unpkg.com/vuelidate@0.7.4/dist/vuelidate.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.js"></script>



<div id='app'>
  <div class="row">
    <div class="col-md-4">
      <b-form-select v-model="$v.todo.$model" :options="todos"></b-form-select>
    </div>
    <div class="col-md-8">
      <code>
        $anyDirty: {{$v.$anyDirty}}
      </code>
    </div>
  </div>
</div>  

Ответ №1:

Проблема в том, что $v.reset() выполняется до рендеринга vue, поэтому входные события происходят после, поэтому трассировка стека будет выглядеть следующим образом

загрузка > установить значения > сбросить проверку > визуализация > событие ввода

Вам нужно поместить сброс внутрь Vue.nextTick , и тогда это сработает, поскольку это изменит выполнение на

загрузка > установить значения > визуализация > событие ввода > сбросить проверку

 Vue.use(vuelidate.default);
const {
  required
} = window.validators;
new Vue({
  el: "#app",
  data: {
    todos: [],
    todo: ""
  },
  async created() {
    var data = await axios.get("https://jsonplaceholder.typicode.com/todos");
    this.todos = data.data.map(d => d.id);
    this.todo = this.todos[0];
    Vue.nextTick(() => {
      this.$v.$reset()
    })
  },
  validations() {
    return {
      todo: {
        required
      }
    };
  }
});  
 <link href="https://unpkg.com/bootstrap-vue@2.0.0-rc.11/dist/bootstrap-vue.css" rel="stylesheet" />
<link href="https://unpkg.com/bootstrap@4.1.3/dist/css/bootstrap.min.css" rel="stylesheet" />

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/bootstrap-vue@2.0.0-rc.11/dist/bootstrap-vue.min.js"></script>
<script src="https://unpkg.com/vuelidate@0.7.4/dist/validators.min.js"></script>
<script src="https://unpkg.com/vuelidate@0.7.4/dist/vuelidate.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.js"></script>



<div id='app'>
  <div class="row">
    <div class="col-md-4">
      <b-form-select v-model="$v.todo.$model" :options="todos"></b-form-select>
    </div>
    <div class="col-md-8">
      <code>
        $anyDirty: {{$v.$anyDirty}}
      </code>
    </div>
  </div>
</div>  

В качестве примечания, вы также можете вызвать Vue.nextTick с this.$nextTick