DateStingPicker component encapsulation

Requirements:

  1. Use the date selection box in the page, and the date format “XXXX year XX month XX day” is displayed in the input box.
  2. Convert the date format to a string when submitting data, such as “20210314”
  3. When you view the data, the date format is XXXX year XX month XX day.

demo

Sequencing – Use software and framework versions

  1. Vue 2.6.11
  2. Ant – design – vue 1.7.1
  3. Moment.js (date-conversion dependency)

Design ideas

  1. The command output must be in the format of XXXX year XX month XX day. View the component librarya-date-picker, and I know that theformatProperty to convert data in an input field to a specific format.
  2. When submitting data, we need to because we are encapsulating components for use in other pagesPlace the value to be submitted from the child to the parentSo in the date component, select the date-off eventchange/inputIs used when the date is selected$emitSets the value to the upper component.
  3. When you view the data on the page, the data is displayed in the form. At this time, you get the string “20210314” from the background data, and format the data as “XXXX year XX month XX day” and display it in the input box.

Specific code process

1. Template Indicates the template area

<template>
  <div>
    <! MomentValue = momentValue = momentValue = momentValue
    <a-date-picker
      :value="momVal"
      :allowClear="allowClear"
      :disabled="disabled"
      :format="dateFormat"
      :mode="mode"
      :placeholder="placeholder"
      @change="dateChanged"
    >
    </a-date-picker>
  </div>
</template>
Copy the code

I’m going to use a couple of attributes here,

  1. Used because it is a encapsulated componentvalueImplement two-way data binding, used in formsallClearYou can also clear the form display and underlying data by clicking the clear button.
  2. Mode is the input box display mode, date, month, year is optional, but the year mode is not very useful, for details, see the next chapter, year year component encapsulation.
  3. Of course there are more than components@changeThe event,@blur.@selectBoth are available and can be used depending on the project’s requirements, but when you use events on the parent component, you need to use events on the child componentpropsAnd uses bidirectional binding in the template section:select="select".

2. Js area

<script>
import moment from 'moment'

export default {
  name: 'dateStringPicker'.props: {
    value: {
      type: [String.Number].default: ' '
    },
    // Return the date format
    dateFormat: {
      type: String.default: 'YYYY year MM month DD day '
    },
    // Type, select year, pass in "year", select year, pass in "month"
    mode: {
      type: String.default: 'date'
    },
    placeholder: {
      type: String.default: 'Please select a date'
    },
    disabled: {
      type: Boolean.default: false
    },
    allowClear: {
      type: Boolean.default: true
    },
    // Determine the two states of input input/change
    triggerChange: {
      type: Boolean.default: true
    }
  },
  data () {
    const dateStr = this.value
    return {
      // Since vUE is data-driven page loading, we need to give value an initial value in data
      momVal: !dateStr ? null : moment(dateStr, this.dateFormat),
      lastValue: ' '}},watch: {
    // The listener here is used to implement design idea 3
    value (val) {
      if(! val) {this.momVal = null
      } else {
        this.momVal = moment(val, 'YYYYMMDD')}}},methods: {
    moment,
    // Here is the change event, used to implement design idea 2, here is the note, at that time when writing still encountered some problems
    dateChanged (mom) {
      // Refer to Note 3
      if(! mom) {if (this.triggerChange) {
          this.$emit('change'.null)}else {
          this.$emit('input'.null)}}else {
        // Refer to Note 1
        this.lastValue = moment(mom).format('YYYYMMDD')
        // Refer to Note 2
        if (this.triggerChange) {
          this.$emit('change'.this.lastValue
        } else {
          this.$emit('input'.this.lastValue)
        }
      }
    }
  }
}
</script>
Copy the code

Matters needing attention:

  1. When we submit data, we pass data to the form through lastValue; If you don’t need formatting you can just use this.momVal = value and pass the same data type as the moment object.

  2. The reason for creating a triggerChange attribute is that there are two cases when using an A-form component in an Ant-Design-Vue component

    • Data submission does not require validation rulesv-modelData binding
    • To verify rules when submitting data, usev-decorator

    In v-Model, clicking on a date-triggered event is input, and in V-decorator, clicking on a date-triggered event is change

  3. Why add a change event to submit data! The reason for mom’s conditional judgment is that after the allClear attribute is added to the form, the symbol “❌” will appear in the form to clear the current input field data. When the form data is cleared, the form will display “no valid” or “NaN”. The reason may be that the initial value data type of the form after the clearing is not correct. Anyway, the solution is to add one! Mom’s condition determines that when the form data is cleared, it re-assigns a null value to the form value, which cannot be “” because value is of type object.

Testing a Demo Instance

<template>
  <div>
    <div class="box">
      <h1>this is dateStringPiker</h1>
      <div class="btn">
        <a-button type="primary" @click="click">Submit data</a-button>
      </div>
      <a-form :form="editForm" layout="inline">
        <! With v-model, a value is thrown from a child component with an input event -->
        <a-form-item label="Date of binding in v-model form">
          <date-string-picker
            v-model="editForm.date"
            :trigger-change="false">
          </date-string-picker>
        </a-form-item>

        <! In cases where validation is required, use a V-decorator binding in the form of a form, while the self component throws a value as change to the upper component.
        <! -- <a-form-item label="v-decorator binding date ">-->
        <! -- <date-string-picker-->
        <! -- v-decorator="['date',{initialValue:''}]"-->
        <! -- :trigger-change="true">-->
        <! -- </date-string-picker>-->
        <! -- </a-form-item>-->
      </a-form>
    </div>
  </div>
</template>

<script>
import dateStringPicker from '@/component/dateStringPicker'

export default {
  name: 'demo'.components: {
    dateStringPicker
  },
  data() {
    return {
      // To use a V-decorator, register the form using the following method
      // editForm: this.$form.createForm(this)

      // Form registration is simpler
      editForm: {
        date: ' '}}},methods: {
    click() {
      console.log('Click the button')
      // V-model binding test commit
      // console.log(this.editForm)

      // v-decorator binding, test data submission
      this.editForm.validateFields((err, value) = > {
        console.log(err)
        console.log(value)
      })
    }
  }
}
</script>

<style scoped lang="less">
.box {
  margin: 30px 30px;
}

.btn {
  margin: 30px 30px;
}
</style>

Copy the code

Find me

Gitee:gitee.com/heyhaiyon/a…

Wechat official account: Heyhaiyang

The Denver nuggets: heyhaiyang

B: Heyhaiyang

Headline number: Heyhaiyang