Vue bootstrap b-form-select устанавливает $ anyDirty для vuelidate в значение true при загрузке - PullRequest
1 голос
/ 08 марта 2019

У меня возникла проблема из-за события input, которое запускается, когда я впервые устанавливаю значение v-model, эти данные загружаются через API; Я понимаю, почему форма устанавливается на грязную (так как она изменяется), но это вызывает проблемы в другом компоненте, который у меня есть, который проверяет, установлен ли флаг $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 Ответ

0 голосов
/ 08 марта 2019

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

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

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

load> set values> render> input input> валидация сброса

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

...