Demand analysis

Critical requirements (absence affects component usage or user experience)

  1. The verification code image format from the back end is processed accordingly
  2. This component is based on the Input component of Ant-Design for encapsulation, encapsulation to the original component attributes, slot selective inheritance
  3. Click the picture to initiate a request to update the verification code. During this period, the input box should be prohibited to fill in, and multiple clicks should be prevented after one click
  4. Packaged new components should also maintain bi-directional data binding capabilities
  5. Provides url interfaces for obtaining verification code images and processing related parameters, and supports POST and GET

Non-critical requirements (for better interaction, etc.)

  1. Components should be extensible, offering a variety of sizes and allowing developers to customize them
  2. Spin load related interactions

implementation

There are four implementations of the overall structure (two types) :

  1. Input box -> SPIN Suspension -> IMG verification code
  2. Spin Hover -> Input box -> IMG verification code
  3. Input box & (spin Suspension -> img verification code)
  4. Spin Hover -> (Input box & img verification code)

In method 1 and 2, the verification code pictures are used as part of the input field (suffix). In method 3 and 4, the verification code pictures and the input field are juxtapoted. In the implementation of component encapsulation, since the input box and verification code in mode 3 and mode 4 are independent from each other, the style will be out of sync, and a lot of style adjustments are needed. This paper adopts mode 2. Mode 2 is shown as follows:

Core code analysis

The mock simulation

const imgSrc = Random.image('1200x820', '#' + Random.string('number', 6), '#ffffff', Random.string('abcdefghijklmnpqrstuvwxyz123456789', 6))
Copy the code

Mock simulation uses Random pictures generated by Random, in which the character range and size can be set. When using components, the request is simulated using the router-mock component, the router-mock component download address, and the router-mock document address

Slot inheritance

<template v-for="(_, slot) of $options.omit(['suffix'],$scopedSlots)" #[slot]="scope" >
    <slot :name="slot" v-bind="scope" />
</template>
<template v-for="(_, slot) of $slots" :slot="slot">
    <slot :name="slot"></slot>
</template>
Copy the code
  1. ScopedSlots, scopedSlots, scopedSlots, slots inherited twice? Although the official vUE documentation says that slots will be exposed as a function of slots and slots will be exposed as a function of slots and scopedSlots, in this form of inheritance, even if you take the named slot, there’s no way to handle the scope that it provides, So you need to inherit the named slot
  2. Underscores are placeholders
  3. Omit omit is a function in Ramda, which should be introduced by import and included in export, and $options should be used for custom components

Image format conversion

/ / if send me pictures directly render the if (/ \. (PNG |, jpe." g|gif|svg)(\? . *)? $/.test(res)) { this.captchaPath = res.data; } / / backend sending data, if it is base64 format, can render else if direct assignment (/ ^ data: image \ / (PNG |, jpe." g|gif|svg); base64,/.test(res)) { this.captchaPath = res.data; Else if (res instanceof ArrayBuffer) {this.captchaPath = 'data:image/ PNG; base64,${btoa(new Uint8Array(res).reduce((data, byte) => data + String.fromCharCode(byte), ''))}`; } // if the mock is a Blob, use the URL. CreateObjectURL () to render the mock. Else {setTimeout(() => {this.captchapath = res.data; }, 2000); }Copy the code

Two-way binding

<a-input :value="value" @change="$emit('change', $event.target.value)">
</a-input>

model: {
    prop: 'value',
    event: 'change',
  },
Copy the code

The default prop for model is “value” and the event is “input”

Network request

Const url= this.url.split("?") const url= this.url.split("? ) [0]; Parse (this.url.split("?")) const data = qs.parse(this.url.split("? )[1]) {const res = await request({url, method: this.method, data})(); if(...) {}}Copy the code

The QS help parameter serialization is referenced here

Encapsulate results & use

Use cases:

<captcha-input2 :url="`/post/captcha? uuid=${uuid}`" v-model="captchaValue" method="post" size="small" allowClear > <template #prefix> <a-icon type="safety"></a-icon> </template> </captcha-input2>Copy the code

Matters needing attention

Component API

This component inherits all the components of the original input box (except for the suffix, where the captcha images use this slot)

parameter instructions type The default
url A request for a captcha image string
method Specifies the URL request type. The options are POST and GET string get
captchaOnly Whether to display only the verification code without the input box boolean false

The source address

Component address Project address

conclusion

To be perfected or solved

  1. Loading — — flash? It should be Mock data
  2. External changes to the UUID to prevent multiple clicks (not currently considered)
  3. Wrong thinking before mode — normal mode, form mode, captcha only mode (continue to improve after use)
  4. Disallow multiple clicks to initiate a request — currently only relying on loading control (network requests need to be improved)
  5. The overall length of the component is fixed, but affected by the image length, the image will be full if it is too long (it will also affect the placeholder display to some extent).
  6. Only the captcha mode is not perfect, who to use, length and width Settings, code optimization, etc

The relevant knowledge

How back-end images are stored

  1. Save the image independently, put the path into the database
  2. Convert images to binary streams and store them directly in the image type field in the database (not recommended)

Display format of front end picture

Images can be displayed in the front end in three ways: URL, Base64, and BLOb

  1. Url: the image path is sent from the back end.
  2. Base64: Not recommended if the image is large and colorful (the string is too large, affecting performance); If loading or table line is relatively small and occupies a network request, it is suitable
  3. Blob: binary stream

Both path and base64 can be assigned to the SRC attribute directly. For the third, you hand over the binary stream to the BLOB object for processing, and then use the BLOB API to generate temporary URL assignments to the SRC attribute.

Three conversion:

Url — > base64 <===> blob

Get, POST, and Query parameters

First of all, Http request methods can be divided into URL request and BODY request according to their data transmission capability. URL request includes but is not limited to GET, HEAD, OPTIONS and TRACE, and BODY request includes but is not limited to POST, PUSH, PATCH and DELETE. For URL class requests, the client cannot write in the body, and the server gets the body empty. For the BODY request, you can either put parameters in the URL or send data through the BODY. When you use the BODY to send data, you send different types of data depending on the content-Type.

The url format is as follows: Pictures from the network – assault and deletion

When encapsulating the verification code component, in order to facilitate the use of developers and unify the style, both GET and POST use Quary parameter transmission mode, if any parameters are directly placed in the URL. The default GET request mode is provided. To change the request type to POST, change the method value to POST.

Input Box input and change events

During bidirectional binding, the problem of deciding between input and change events is encountered. Input as event and value as props is the default configuration of bidirectional binding using Model. In some cases, the results of input and change are consistent. But there is a fundamental difference between the two, to be continued.

Reference 1- What is the difference between writing a Post method parameter in a body and in a URL?