Demand analysis
Critical requirements (absence affects component usage or user experience)
- The verification code image format from the back end is processed accordingly
- This component is based on the Input component of Ant-Design for encapsulation, encapsulation to the original component attributes, slot selective inheritance
- 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
- Packaged new components should also maintain bi-directional data binding capabilities
- Provides url interfaces for obtaining verification code images and processing related parameters, and supports POST and GET
Non-critical requirements (for better interaction, etc.)
- Components should be extensible, offering a variety of sizes and allowing developers to customize them
- Spin load related interactions
implementation
There are four implementations of the overall structure (two types) :
- Input box -> SPIN Suspension -> IMG verification code
- Spin Hover -> Input box -> IMG verification code
- Input box & (spin Suspension -> img verification code)
- 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
- 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
- Underscores are placeholders
- 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
- Loading — — flash? It should be Mock data
- External changes to the UUID to prevent multiple clicks (not currently considered)
- Wrong thinking before mode — normal mode, form mode, captcha only mode (continue to improve after use)
- Disallow multiple clicks to initiate a request — currently only relying on loading control (network requests need to be improved)
- 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).
- 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
- Save the image independently, put the path into the database
- 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
- Url: the image path is sent from the back end.
- 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
- 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?