Vue bootstrap b-form-select 在加载时将 vuelidate 的 $anyDirty 设置为 true
Vue bootstrap b-form-select sets vuelidate's $anyDirty to true on load
我遇到的问题是由于 input
事件导致 运行 当我第一次为 v-model
设置值时,此数据是通过API;我理解为什么表单被设置为脏(因为它正在被更改)但这会导致我拥有的另一个组件出现问题,该组件检查加载数据后 $v.$anyDirty
flag is sets to true and if it is, creates a pop up to say "are you sure you want to navigate away" but calling $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>
问题是 $v.reset()
在 vue 渲染之前 运行 所以输入事件发生在之后,所以堆栈跟踪看起来像这样
load > set values > reset validation > render > input event
您需要将重置放在 Vue.nextTick
中,然后它将起作用,因为它将执行更改为
load > set values > render > input event > reset validation
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>
请注意,您还可以用 this.$nextTick
调用 Vue.nextTick
我遇到的问题是由于 input
事件导致 运行 当我第一次为 v-model
设置值时,此数据是通过API;我理解为什么表单被设置为脏(因为它正在被更改)但这会导致我拥有的另一个组件出现问题,该组件检查加载数据后 $v.$anyDirty
flag is sets to true and if it is, creates a pop up to say "are you sure you want to navigate away" but calling $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>
问题是 $v.reset()
在 vue 渲染之前 运行 所以输入事件发生在之后,所以堆栈跟踪看起来像这样
load > set values > reset validation > render > input event
您需要将重置放在 Vue.nextTick
中,然后它将起作用,因为它将执行更改为
load > set values > render > input event > reset validation
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>
请注意,您还可以用 this.$nextTick
Vue.nextTick