In daily iterative development, we often encounter a scenario where the user is required to enter an amount in a form and verify the format of the amount. You’ve probably seen this before, but for now, we need to make sure that when the user leaves the input field (out of focus), the input is presented to the user as a three-digit number separated by commas. And when the final amount is submitted, the value of the parameter is still a normal number, excluding commas.

When faced with this requirement, the first thing to think about is that the “amount input box in the form” is a common feature. Since this is a common function, we want to abstract it and encapsulate it so that it can be used in any form at any time, using one line of code instead of repeating tasks.

Just like the form items, we need to pass the component the label, the key, the placeholder with the bound value to be displayed in the form; You also need to pass in the entire form object, the rules of the form. Also, given that we need to show a mask layer the formatted amount, we also need to pass width to determine the mask layer width.

Note our above requirement that when the blur event is triggered by the input box, we first need to verify that the user input is a positive number with two decimal digits remaining. Here we use the rules passed in to verify. If it passes the verification, the amount after formatting will be expanded. If it does not pass the verification, the element-UI’s verification rule prompt will be triggered. Note that the blurInput method triggered by @blur is used to remove the 0 in front of the input to verify that it meets the verification criteria, and finally to determine whether to expand the formatted amount.

If it works and passes the verification, you need to format the amount based on the input. Obtained by computed computation.

The design idea of the components is roughly as follows:

The complete component code is as follows:

<template lang="pug">
el-form-item.price-parent(:label="label" :prop="prop" )
  el-input(:style="`width: ${width}px`" ref="input" v-model="form.deceivedAmount" :placeholder="placeholder" @blur="blurInput" @focus="focusInput")
  .price-mask(:style="`width: ${width -30}px`" v-show="showFormatPrice" @click="focusInput") {{formaterPrice}}
</template>

<script>
export default {
  name: 'priceInput'.props: {
    label: {
      type: String.default: ' ',},prop: {
      type: String.default: ' ',},placeholder: {
      type: String.default: 'Please enter',},width: {
      type: Number.default: 140,},form: {
      type: Object.default: () = > ({
        deceivedAmount: ' ',})},rules: {
      type: Object.default: () = > { },
    },
  },
  data () {
    return {
      showFormatPrice: false.// Whether to display masks}},computed: {
    formaterPrice () {
      if (
        this.form.deceivedAmount ! = =' ' &&
        this.form.deceivedAmount ! = =null
      ) {
        // Remove the preceding 0
        const integer = this.form.deceivedAmount.split('. ') [0]
        const decimal = this.form.deceivedAmount.split('. ') [1]?`.The ${this.form.deceivedAmount.split('. ') [1]}`
          : ' '
        return `${integer
          .toString()
          .replace(/ (? = (? ! ^)(\d{3})+$)/g.', ')}${decimal}`
      } else {
        return ' '}}},methods: {
    // Focus the amount input box
    focusInput () {
      this.showFormatPrice = false
      this.$refs.input.focus()
    },
    // Lose focus amount input box
    blurInput () {
      if (this.form.deceivedAmount ! = =' ') {
        // Remove the preceding 0
        const integer = Number(this.form.deceivedAmount.split('. ') [0])
        const decimal = this.form.deceivedAmount.split('. ') [1]?`.The ${this.form.deceivedAmount.split('. ') [1]}`
          : ' '
        this.form.deceivedAmount = isNaN(`${integer}${decimal}`)?this.form.deceivedAmount
          : `${integer}${decimal}`
        if (typeof this.rules[this.prop][0].pattern ! = ='object') {
          throw 'Please ensure that rules[The ${this.prop}][0]. Pattern is a regular expression
          return
        }
        this.showFormatPrice = this.rules[this.prop][0].pattern.test(
          this.form.deceivedAmount,
        )
      }
    },
  },
}
</script>

<style lang="less" scoped>
.price-mask {
  position: absolute;
  z-index: 2;
  top: 1px;
  left: 125px;
  background: white;
  width: 110px;
  overflow: auto;
  font-size: 13px;
}
</style>
Copy the code

The way you use it in a form is exactly the same as if you just wrote an el-form-item, you just import it.

// Use method:
<template lang="pug">
el-form(:model="form" ref="form" label="180px" :label-suffix="' : '" :rules="rules")
    priceInput(:form.sync = "form" :width = "150" label = "The amount" prop = "deceivedAmount" :rules = "rules")
</template>

<script>
import priceInput from '@self/components/priceInput'
data() {
  return {
    form: {
      deceivedAmount: null,},rules: {
      deceivedAmount: [{pattern: 1000000000.0 $/ $1000000000, | ^ ^ | ^ 1000000000.00 $| ^ [+] {0, 1} (\ d {0, 9}) $| ^ [+] {0, 1} (\ d {0, 9} \ \ d {1, 2}) $/,
          message: 'Please enter a positive number from 0 to 1 billion, leaving two decimal places.'.trigger: 'blur',},],},}}components: {
  priceInput,
}
</script>
Copy the code

Making the address

Github.com/Gesj-yean/v…