当前位置:网站首页>Vant3+ts encapsulates uploader upload image component
Vant3+ts encapsulates uploader upload image component
2022-06-12 17:48:00 【Enthusiastic learning】
Because this component is used many times in the project So I sealed it myself
vant The components of need to be in
:after-read Then upload the image to the server
Select or take photos on your mobile phone The return format is [{name:xxx,data:base64,xxxxx},{name:xxx,data:base64,xxxxx}]
and Component echo is based on flie Object or URL
So before uploading hold Back to base64 Turn into file object
You need to compress the image before uploading it to the interface
The code of the whole component is as follows
The logic of uploading pictures is First step , hold fileNames Upload to the interface provided in the background The return format is {url:xxx,path:xxx,contentType:xxx}, The second step , The return of url put Ask for file The request succeeds only when the object is transferred to the background , The third step , Taking the first step back path Send it to the background to return the picture URL( My echo here is based on url)
In the code count Pass values to the parent component only after all the interface requests are completed
<template>
<van-uploader v-model="imgList" :max-count="limit" :multiple="multiple" :before-delete="beforeDeleteBack"
:after-read="afterRead" :accept="fileType" :disabled="disabled" @click-upload="handleClick" />
</template>
<script lang="ts" setup>
import { reactive, ref, toRefs, watch, nextTick, unref } from 'vue'
import { Toast, Dialog } from 'vant'
import AjaxTestService from '@/api/test'
import { getPhoto } from '@/utils/nativeAPI'
import ImageCompressor from 'image-compressor.js'
import type {
UploaderProps,
UploaderInstance,
UploaderResultType,
UploaderFileListItem,
} from 'vant'
interface Props {
imgList: Array<any> // File address - Two way binding
limit?: number // Number of documents
multiple?: boolean // Whether to choose more than one
fileType?: string // file type
disabled?: boolean // Whether to disable uploading
}
const props = withDefaults(defineProps<Props>(), {
limit: 4,
multiple: true,
fileType: 'image/*',
disabled: false
})
const imgList = ref<Array<any>>([])
const emit = defineEmits<{
(e: "update:imgList", imgList: any): void;
(e: "fileList", filePath: any): void;
}>();
watch(
() => props.imgList,
val => {
console.log(unref(val), "watch monitor imgList");
// console.log(imgList.value.length, " The length of the picture ");
imgList.value = val.map(v => {
if (typeof v == 'string') {
return { url: v }
}
else {
return v
}
});
},
{ immediate: true, deep: true }
);
// Delete pictures
function beforeDeleteBack(file: any, detail: any) {
console.log(" Delete operation :file", file, "detail,", detail)
console.log(imgList.value, " From here img")
// return new Promise<boolean>((resolve, reject) => {
Dialog.confirm({
confirmButtonText: ' confirm ',
cancelButtonText: ' Cancel ',
message: ' Confirm to delete the fault picture ',
})
.then((res) => {
console.log(tempFile, " Delete ")
tempFile.splice(detail.index, 1)
imgList.value.splice(detail.index, 1)
emit("update:imgList", imgList.value);
Toast({
message: ' Delete successful ',
icon: 'checked',
iconSize: '20px',
className: 'tipToast'
})
// resolve(true)
})
.catch((error) => {
// Toast({
// message: ' Cancelled ',
// })
// reject(error)
})
// })
}
// take base64 Convert to blob File stream
function dataURLtoBlob(dataurl: any) {
let arr = dataurl.split(',')
let mime = arr[0].match(/:(.*?);/)[1]
let bstr = window.atob(arr[1])
let n = bstr.length
let u8arr = new Uint8Array(n)
console.log(mime, "mime")
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], { type: mime });
}
// then blob Convert to file
function blobToFile(theBlob: any, fileName: any) {
theBlob.lastModifiedDate = new Date();
theBlob.name = fileName;
return theBlob;
}
// call
// var blob = dataURLtoBlob(base64Data);
// var file = blobToFile(blob, imgName);
// take base64 turn file object Because again ios There is an adaptation problem, so this method is not used .
function base64ToFile(urlData: any, fileName: string) {
let arr = urlData.split(',');
let mime = arr[0].match(/:(.*?);/)[1];
let bytes = window.atob(arr[1]); // decode base64
let n = bytes.length
let ia = new Uint8Array(n);
while (n--) {
ia[n] = bytes.charCodeAt(n);
}
//u8arr
return new File([ia], fileName, { type: mime });
}
// Click the upload area to trigger the event First, put fanhuide blobToFile(v.data, v.name)
function handleClick() {
console.log(" Click upload event to trigger ")
getPhoto((res: any) => {
console.log(typeof res, " Select the file type to return ")
// console.log(res, " Select the returned file ")
if (typeof res == 'string') {
res = JSON.parse(res)
res = res.map((v: any) => {
return {
type: 'image/jpeg',
name: v.name,
file: blobToFile(dataURLtoBlob(v.data), v.name)
}
})
}
afterRead(res)
})
}
// You need to compress the image before uploading
function compressFile(file: any, callback: (cres: any) => void) {
new ImageCompressor(file, {
quality: 0.4, // The compression quality
width: 500,
height: 500,
checkOrientation: false, // Flip the picture , The default is false
success(result) {
console.log(result, "result Compressed files ")
callback(result);
},
error(e) {
JSON.stringify(e)
}
})
}
//
function beforeRead() {
console.log(" Click upload event to trigger ")
}
// Upload files to the server
let tempFile: { file: { name: any; }; path: string; url: string; name: any, type: string }[] = []
function afterRead(file: any) {
console.log(file, " stay afterRead")
if (file.length) { // instanceof Array The radio
tempFile = tempFile.concat(file)
} else { // multi-select
tempFile.push(file)
}
if (tempFile.length > 4) {
console.log(tempFile.length, " In judgment tempFile The length of ")
tempFile.splice(4)
}
console.log(typeof tempFile, "typeof tempFile")
console.log(tempFile, "tempFile Processing is complete ")
console.log(tempFile.length, "tempFile The length of processing completed ")
// There is no problem with this cycle on the browser side , The format on the mobile phone returns [{name:xxx,data:base64},{name:xxx}]
let parma = {
fileNames: tempFile.map((fileItem: { file: { name: any; }; }) => fileItem.file.name).join(",")
}
// console.log(parma, ' Print parameters ')
// The interface provided by the background obtains the temporary path
AjaxTestService.getUploadUrl(parma).then((res) => {
let count = 0
res.data.forEach((item: { url: any; path: any, contentType: string }, index: any) => {
tempFile[index].path = item.path
tempFile[index].type = item.contentType
// This step is compression
compressFile(tempFile[index].file, (cres: any) => {
console.log(cres, ' Compressed file file')
// Take the returned url put The request is considered to be successful in uploading the picture
AjaxTestService.uploadImg(item.url, cres, item.contentType).then(_res => {
console.log(_res, " Upload successful ")
// Return temporary picture information according to the background interface
AjaxTestService.getTempFileUrl({ pathNames: item.path }).then(resUrl => {
console.log(res, " Get temporary url")
tempFile[index].url = resUrl.data[0]
count += 1
if (count == res.data.length) {
imgList.value = tempFile
emit("update:imgList", tempFile)
console.log(tempFile.length, "tempFile The length of ")
console.log(tempFile, "3 Step interface completed imgList")
}
})
}).catch(err => {
})
})
});
}).catch(err => {
})
}
defineExpose({
// handleForm
});
</script>
<style scoped lang="scss">
</style>
边栏推荐
- 续2 asp.net core 路由程序基础使用演示0.2 默认控制器数据的获取到
- 内核中断整体流程图
- 错误记录:IllegalStateException: Optional int parameter ‘xxxx‘ is
- 《用户体验要素:以用户为中心的产品设计》笔记
- 重构--梳理并分解继承体系
- String的split方法的使用
- 消息队列存储消息数据的 MySQL 表格
- Risc-v ide mounriver studio v1.60 update point introduction
- Arm64 Stack backtrack
- Learn the mitmproxy packet capturing tool from scratch
猜你喜欢
DRM 驱动 mmap 详解:(一)预备知识
Memory control of node
MySQL学习笔记
龙芯处理器内核中断讲解
SSM integrates FreeMarker and common syntax
内核中断整体流程图
C operation database added business data value content case school table
Message queuing MySQL tables that store message data
Yyds dry goods inventory leetcode question set 911 - 920
Unprecedented analysis of Milvus source code architecture
随机推荐
Notes on user experience elements: user centered product design
Common dependencies of SSM
Lightweight and convenient small program to app technology solution to realize interconnection with wechat / traffic app
Use of split method of string
新媒体运营素材网站分享,让你创作时事半功倍
32-bit MCU mm32f0040 with smart micro high performance M0 kernel
ftrace
Cesium parabolic equation
AlibabaProtect.exe如何删除、卸载
566. reshaping the matrix
Idea common shortcut keys
118. Yanghui triangle (dynamic planning)
Figma from getting started to giving up
1.5 什么是架构师(连载)
Schedule update | 2022 Microsoft and Intel hacker song competition is in hot registration
Exclusive interview with oppo find X5 Product Manager: deeply cultivate self-developed chips to create the ultimate flagship experience with the highest standards
Original error interface
App中快速复用微信登录授权的一种方法
Database SQL operation Basics
三代DRI的变化