当前位置:网站首页>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>边栏推荐
- Two ways of tensorflow2 training data sets
- Detailed description of SQL cursor and example of internal recycling
- 数据库SQL操作基础
- vant3 +ts 封装简易step进步器组件
- I heard that distributed IDS cannot be incremented globally?
- Arm64 stack backtracking
- Yyds dry goods inventory leetcode question set 911 - 920
- 小程序+App,低成本获客及活跃的一种技术组合思路
- Application case of smart micro 32-bit MCU for server application cooling control
- Authorization in Golang ProjectUseing Casbin
猜你喜欢

Guitar Pro tutorial how to set up a MIDI keyboard

Byte flybook Human Resources Kit three sides

Some introduction to FPC flexible circuit board design

进阶之大山-asp.net core 路由程序基础使用演示0.1

淘宝Native研发模式的演进与思考 | DX研发模式

Hangzhou AI developer meetup registration opens!

TensorFlow求梯度时提示TypeError: unsupported operand type(s) for *: ‘float‘ and ‘NoneType‘

Yyds dry goods inventory leetcode question set 911 - 920

WinForm, crystal report making

赛程更新| 2022微软与英特尔黑客松大赛火热报名中
随机推荐
First acquaintance with go language
赛程更新| 2022微软与英特尔黑客松大赛火热报名中
电控学习 第二周
Arm64棧回溯
Codeforces Round #398 (Div. 2) D. Cartons of milk
JDBC several pits
Detailed description of SQL cursor and example of internal recycling
Use of split method of string
Bug record: data truncation: incorrect datetime value:
Saturated! Can't future programmers work anymore?
Channel Original
SSM集成FreeMarker以及常用语法
Flink 维表异步查询的实现以及问题排查
566. reshaping the matrix
Volcano engine held a video cloud technology force summit and released a new experience oriented video cloud product matrix
MySQL学习笔记
迄今微软不同时期发布的SQL Server各版本之间的大致区别,供参考查阅
MIPS 通用寄存器 + 指令
小程序和App同时拥有?两者兼得的一种技术方案
《用户体验要素:以用户为中心的产品设计》笔记