【问题标题】:end date must be less than start date, Vuelidate and VueJs结束日期必须小于开始日期,Vuelidate 和 VueJs
【发布时间】:2021-07-02 18:39:24
【问题描述】:

我在进行表单验证时遇到问题。我有一个开始日期和一个结束日期。我需要确认结束日期大于开始日期。 我正在使用 vuejs 和 vuelidate。 我正在使用 Input.vue 组件,它有一个标准输入,可以在其他形式中重用。我还有一个 Form.vue 组件,里面有 Input.vue。并且这个 Form.vue 组件在创建新事件的模式和编辑模式中都会被调用。 我的问题是验证事件何时被编辑。如果您选择的结束日期小于开始日期,则不允许保存信息,没关系。但是,当尝试通过选择一个大于开始日期的日期来更正它并再次单击保存时,它似乎不再调用验证。这样,结束日期必须大于初始日期的错误不会消失。我做了几个测试,并注意到在编辑时发生错误后没有调用验证。我不知道为什么。

组件 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开发者工具了吗?这应该显示触发了哪些事件及其值
  • 请尽量减少包含的代码并将其集中到与您的问题相关的最低限度。
  • @SuperDJ 一切安装正确。我在控制台上没有错误。这是一个自定义验证,我根据可用文档中的示例创建了它。原来的 vuelidate 验证器工作正常,只有这个自定义的不是..
  • @Grazi 不应该 end_at_date: { required: function(value) { return isAfterDate(value, this.edit_event); } },end_at_date: { required,isAfterDate(value, this.edit_event), } }, 喜欢 vuelidate.js.org/#custom-validators
  • @Grazi 我指的不是控制台,我指的是chrome.google.com/webstore/detail/vuejs-devtools/…

标签: javascript vue.js vuelidate


【解决方案1】:

Vue.set 解决了我的问题。我意识到我试图检测我后来自己添加的属性的变化。所以我在添加属性的时候不得不使用Vue.set,这样我以后可以检测到变化,然后正确地验证表单。感谢任何试图帮助我的人!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-20
    • 2017-09-26
    • 2018-03-06
    相关资源
    最近更新 更多