结束日期必须小于开始日期,Vuelidate 和 VueJs
end date must be less than start date, Vuelidate and VueJs
我在进行表单验证时遇到问题。我有一个开始日期和一个结束日期。我需要确认结束日期大于开始日期。
我正在使用 vuejs 和 vuelidate。
我正在使用一个 Input.vue 组件,它有一个标准输入,可以在其他形式中重复使用。我还有一个 Form.vue 组件,里面有 Input.vue。这个 Form.vue 组件在创建新事件的模式和编辑模式中都会被调用。
我的问题在于验证事件何时被编辑。如果您 select 结束日期小于开始日期,则不允许保存信息,没关系。但是,当尝试通过 selecting 一个大于开始日期的日期来更正它并再次单击保存时,它似乎不再调用验证。这样,结束日期必须大于初始日期的错误就不会消失。我做了几次测试,发现在编辑时发生错误后不会调用验证。不知道为什么。
组件Input.vue:
<template>
<b-form-group :label="label" :label-for="labelFor">
<b-form-input
:id="labelFor"
v-model="value"
:type="type"
:placeholder="placeholder"
:class="{ 'is-invalid': this.isInvalid }"
required>
</b-form-input>
<slot></slot>
</b-form-group>
</template>
<script>
export default {
name: 'InputForm',
props: [ 'label', 'labelFor', 'vModel', 'type', 'placeholder', 'isInvalid' ],
computed: {
value: {
get() {
return this.vModel
},
set(value) {
this.newValue = value
return this.$emit('emitValue', this.newValue)
}
}
},
}
</script>
组件Form.vue:
<template>
<b-form>
....
<InputForm
class="col-8 pl-0"
:label="'*Início'"
:labelFor="'event_start_at_date'"
:vModel="event.start_at_date"
:type="'date'"
@emitValue="($event) => event.start_at_date = $event"
/>
<InputForm
class="col-4 pr-0"
v-if="!event.all_day"
:labelFor="'event_start_at_time'"
:vModel="event.start_at_time"
:type="'text'"
@emitValue="($event) => event.start_at_time = $event"
/>
</b-col>
<b-col cols="12" lg="6" class="d-flex align-items-end">
<InputForm
class="col-8 pl-0"
:label="'*Fim'"
:labelFor="'event_end_at_date'"
:type="'date'"
:vModel="event.end_at_date"
@emitValue="($event) => event.end_at_date = $event"
:isInvalid="invalid.end_at_date.$error"
>
<b-form-invalid-feedback v-if="this.submitted" :state="invalid.end_at_date.$error == 0">Fim deve ser maior que início.</b-form-invalid-feedback>
</InputForm>
<InputForm
class="col-4 pr-0"
v-if="!event.all_day"
:labelFor="'event_end_at_time'"
:vModel="event.end_at_time"
:type="'text'"
:isInvalid="invalid.end_at_date.$error"
:class="{ 'error' : invalid.end_at_date.$error }"
@emitValue="($event) => event.end_at_time = $event"
/>
...
</b-form>
</template>
export default {
name: 'Form',
props: [ 'event', 'event_shared', 'error', 'submitted' ],
components: { Input },
computed: {
invalid() {
if(this.error.edit_event != undefined) {
return this.error.edit_event
} else if(this.error.event != undefined) {
return this.error.event
} else {
return false;
}
},
stateInvalid() {
if(this.error.edit_event != undefined) {
return this.error.edit_event
} else if(this.error.event != undefined) {
return this.error.event
} else {
return 0;
}
},
},
watch: {
event() {
let newEvent = this.event
this.$emit('emitObj', newEvent)
},
},
}
</script>
组件ModalEditEvent.vue:
...
<VWarningErrorForm v-if="$v.$error" />
<FormEvent
:event="edit_event"
:event_shared="get_shared_users_id"
:error="this.$v"
:submitted="this.submitted"
@emitObj="($event) => edit_event = $event"
/>
...
<b-button
v-if="editEvent && !view_popover_save"
variant="primary" type="submit" @click="save()">Gravar</b-button>
...
<script>
import moment from 'moment';
import { required } from "vuelidate/lib/validators";
import isAfterDate from '@/functions/isAfterDate'
...
validations: {
edit_event: {
name: {
required
},
end_at_date: {
required: function(value) {
return isAfterDate(value, this.edit_event);
}
},
},
},
...
save() {
this.submitted = true;
this.$v.$touch();
if(!this.$v.$error) {
....
}
},
验证
import moment from 'moment';
function isAfterDate(value, vm) {
let hour = function(att) {
return `${att[0]}${att[1]}`;
}
let minute = function(att) {
return `${att[3]}${att[4]}`;
}
let start = moment(vm.start_at_date).set({hour: hour(vm.start_at_time), minute: minute(vm.start_at_time) })._d
let end = moment(vm.end_at_date).set({hour: hour(vm.end_at_time), minute: minute(vm.end_at_time) })._d
return end >= start;
}
export default isAfterDate;
Vue.set 解决了我的问题。我意识到我正在尝试检测我后来自己添加的 属性 的变化。所以我必须在添加 属性 时使用 Vue.set,这样我可以稍后检测到更改,然后正确验证表单。感谢所有试图帮助我的人!
我在进行表单验证时遇到问题。我有一个开始日期和一个结束日期。我需要确认结束日期大于开始日期。 我正在使用 vuejs 和 vuelidate。 我正在使用一个 Input.vue 组件,它有一个标准输入,可以在其他形式中重复使用。我还有一个 Form.vue 组件,里面有 Input.vue。这个 Form.vue 组件在创建新事件的模式和编辑模式中都会被调用。 我的问题在于验证事件何时被编辑。如果您 select 结束日期小于开始日期,则不允许保存信息,没关系。但是,当尝试通过 selecting 一个大于开始日期的日期来更正它并再次单击保存时,它似乎不再调用验证。这样,结束日期必须大于初始日期的错误就不会消失。我做了几次测试,发现在编辑时发生错误后不会调用验证。不知道为什么。
组件Input.vue:
<template>
<b-form-group :label="label" :label-for="labelFor">
<b-form-input
:id="labelFor"
v-model="value"
:type="type"
:placeholder="placeholder"
:class="{ 'is-invalid': this.isInvalid }"
required>
</b-form-input>
<slot></slot>
</b-form-group>
</template>
<script>
export default {
name: 'InputForm',
props: [ 'label', 'labelFor', 'vModel', 'type', 'placeholder', 'isInvalid' ],
computed: {
value: {
get() {
return this.vModel
},
set(value) {
this.newValue = value
return this.$emit('emitValue', this.newValue)
}
}
},
}
</script>
组件Form.vue:
<template>
<b-form>
....
<InputForm
class="col-8 pl-0"
:label="'*Início'"
:labelFor="'event_start_at_date'"
:vModel="event.start_at_date"
:type="'date'"
@emitValue="($event) => event.start_at_date = $event"
/>
<InputForm
class="col-4 pr-0"
v-if="!event.all_day"
:labelFor="'event_start_at_time'"
:vModel="event.start_at_time"
:type="'text'"
@emitValue="($event) => event.start_at_time = $event"
/>
</b-col>
<b-col cols="12" lg="6" class="d-flex align-items-end">
<InputForm
class="col-8 pl-0"
:label="'*Fim'"
:labelFor="'event_end_at_date'"
:type="'date'"
:vModel="event.end_at_date"
@emitValue="($event) => event.end_at_date = $event"
:isInvalid="invalid.end_at_date.$error"
>
<b-form-invalid-feedback v-if="this.submitted" :state="invalid.end_at_date.$error == 0">Fim deve ser maior que início.</b-form-invalid-feedback>
</InputForm>
<InputForm
class="col-4 pr-0"
v-if="!event.all_day"
:labelFor="'event_end_at_time'"
:vModel="event.end_at_time"
:type="'text'"
:isInvalid="invalid.end_at_date.$error"
:class="{ 'error' : invalid.end_at_date.$error }"
@emitValue="($event) => event.end_at_time = $event"
/>
...
</b-form>
</template>
export default {
name: 'Form',
props: [ 'event', 'event_shared', 'error', 'submitted' ],
components: { Input },
computed: {
invalid() {
if(this.error.edit_event != undefined) {
return this.error.edit_event
} else if(this.error.event != undefined) {
return this.error.event
} else {
return false;
}
},
stateInvalid() {
if(this.error.edit_event != undefined) {
return this.error.edit_event
} else if(this.error.event != undefined) {
return this.error.event
} else {
return 0;
}
},
},
watch: {
event() {
let newEvent = this.event
this.$emit('emitObj', newEvent)
},
},
}
</script>
组件ModalEditEvent.vue:
...
<VWarningErrorForm v-if="$v.$error" />
<FormEvent
:event="edit_event"
:event_shared="get_shared_users_id"
:error="this.$v"
:submitted="this.submitted"
@emitObj="($event) => edit_event = $event"
/>
...
<b-button
v-if="editEvent && !view_popover_save"
variant="primary" type="submit" @click="save()">Gravar</b-button>
...
<script>
import moment from 'moment';
import { required } from "vuelidate/lib/validators";
import isAfterDate from '@/functions/isAfterDate'
...
validations: {
edit_event: {
name: {
required
},
end_at_date: {
required: function(value) {
return isAfterDate(value, this.edit_event);
}
},
},
},
...
save() {
this.submitted = true;
this.$v.$touch();
if(!this.$v.$error) {
....
}
},
验证
import moment from 'moment';
function isAfterDate(value, vm) {
let hour = function(att) {
return `${att[0]}${att[1]}`;
}
let minute = function(att) {
return `${att[3]}${att[4]}`;
}
let start = moment(vm.start_at_date).set({hour: hour(vm.start_at_time), minute: minute(vm.start_at_time) })._d
let end = moment(vm.end_at_date).set({hour: hour(vm.end_at_time), minute: minute(vm.end_at_time) })._d
return end >= start;
}
export default isAfterDate;
Vue.set 解决了我的问题。我意识到我正在尝试检测我后来自己添加的 属性 的变化。所以我必须在添加 属性 时使用 Vue.set,这样我可以稍后检测到更改,然后正确验证表单。感谢所有试图帮助我的人!