Uploader upload of vant
The interaction of the vant uploader component is that a series of callback functions will be triggered after clicking upload. If you want to implement the pop-up prompt first when clicking the uploader, and then upload the file after selecting OK.
Generally speaking, wrap an element outside the uploader component, and then set the component to disable mode. When the external element state changes, change the disabled value of the component, and then use the choiceFile provided by vant to obtain the Uploader instance through ref and call the instance method to re-activate the file selection.
The main steps are as follows
First, we can wrap a layer of div outside the uploader component
<span @click="handleClick" v-if="isconfirm" class="message" ></span> <van-uploader v-model="fileList" :after-read="afterRead" :disabled="isconfirm" ref="uploadImg" />
Then define it in data and methods
data() { return { fileList: [], isconfirm: true }; methods: { handleClick() { this.$dialog .confirm({ message: "test,test,test" }) .then(() => { = false; this.$(); }) .catch(() => { = true; }); }, }
When you see this, please note that the version supported by the choiceFile method is v2.5.6 or above. If there is no effect, first check whether the version you installed meets the requirements.
After checking, the version also meets the requirements, but this.$() just has no effect. What's going on?
It turns out that it is related to the browser execution mechanism event loop. Whenever the choicefile is executed, the component is still in disabled mode and cannot be adjusted. In fact, the isconfirm state has not changed yet, so the selection of the file is not visible. You can use a setTimeout or this.$nextTick() in vue to solve it.
setTimeout(() => { this.$(); }, 0); this.$nextTick(() => { this.$(); });
Uploader image compression for vant file upload
Why compress the picture?
With the development of technology, mobile phone pixels are getting better and better, and the pictures taken are getting clearer and clearer. The clearer the picture, the larger the volume. When the mobile terminal uploads a large image, it will stutter and the request timeout will occur.
When the picture is too large, the image preview will also be very slow, so the picture needs to be compressed when the picture is uploaded.
Uploader does not support image compression in the file upload component in the vant, because there are multiple places in the business scenario that need to compress the image when uploading images, so I encapsulated a new component based on the Uploader.
Uploader component encapsulation
This component encapsulates Uploader based on vant file
API
Attribute name | Attribute description | default value |
---|---|---|
quality |
Compression quality [0-1] | 0.5 |
compressSwitch |
Whether to enable compression | false |
threshold |
Compression starts to reach this size [500k] | 500 |
Please refer to the Uploader attribute for Vant file uploadvant official website
Template section
<template> <van-uploader :fileList="$" :before-read="beforeReadFn" v-bind="$attrs" v-on="$listeners"/> </template>
Javascript part
export default { name: 'van-small-upload', props: { quality:{ type:Number, default:0.1 }, compressSwitch:{ type:Boolean, default:false }, threshold:{ type:Number, default:500 }, beforeRead:{ type: Function, default:()=>true } }, data() { return { } }, methods: { // Process pictures imgPreview(file,index) { ('Processing pictures Fn...'); let self = this // See if the FileReader is supported or not if (!file || !) return; const size = /1024 (`Image size ===> ${/1024}k`); ('Image compression:',?'open':'close'); ('Image compression threshold:',+'k'); ('Image compression reduces frame value:',); if (/^image/.test() && size >= && ) { // Create a reader let reader = new FileReader() // Convert picture 2 to base64 format (file) // Callback after successful reading = function() { let result = let img = new Image() = result = function() { // Compression let data = (img,,) (`After compression ===>${/1024}k`); self.$[index].content = data.base64Data self.$[index].file = } } } }, // Compress pictures compress(img, name, type) { let canvas = ('canvas') let ctx = ('2d') //Tile canvas let tCanvas = ('canvas') let tctx = ('2d') // let initSize = ; let width = let height = //If the image is larger than four million pixels, calculate the compression ratio and press the size to below 4 million let ratio if ((ratio = (width * height) / 4000000) > 1) { // ("Greater than 4 million pixels"); ratio = (ratio) width /= ratio height /= ratio } else { ratio = 1 } = width = height // Back color = '#fff' (0, 0, , ) //If the pixels of the picture are greater than 1 million, use tile painting let count if ((count = (width * height) / 1000000) > 1) { // ("More than 100W pixels"); count = ~~((count) + 1) // Calculate how many pieces of tiles to be divided into // Calculate the width and height of each tile let nw = ~~(width / count) let nh = ~~(height / count) = nw = nh for (let i = 0; i < count; i++) { for (let j = 0; j < count; j++) { (img, i * nw * ratio, j * nh * ratio, nw * ratio, nh * ratio, 0, 0, nw, nh) (tCanvas, i * nw, j * nh, nw, nh) } } } else { (img, 0, 0, width, height) } //Compress let ndata = ('image/jpeg', ) = = = = 0; return {base64Data:ndata,fileData:(ndata,name,type)} }, //Convert base64 to file dataURLtoFile(dataurl,name,type) { name = name ? name : 'picture' type = type ? type : 'jpg' var arr = (','), bstr = atob(arr[1]), n = , u8arr = new Uint8Array(n) while (n--) { u8arr[n] = (n) } return new File([u8arr], name, { type: type }) }, beforeReadFn(file,detail){ const {index} = detail (file,index) return (...arguments); } }, mounted(){ } };
Example of usage
<SmUpload v-model="fileList" :before-read="beforeRead" :compressSwitch="true" :quality="0.5"/>
The above is personal experience. I hope you can give you a reference and I hope you can support me more.