使用my.uploadFile、 my.chooseImage 的方式实现图片上传
注意: 使用该方式上传文件,后端也需要参照官方文档进行修改
opendocs.alipay.com/mini/api/km…
一、展示效果
二、上代码
(一)、上传组件
upload-image.axml
<view catchTap="handleSelectImage" class="upload-container">
<view class="upload" a:for="{{imageUrl}}">
<view class="clear" catchTap="handleDelete" data-index="{{item}}">
<am-icon type="CloseCircleFill" color="#333333" size="x-small" /></view>
<view class="loading" a:if="{{item.status == 'fail' ? true : false}}">
<loading type="spin" color="pink" size="small" text="上传中..." loading="{{true}}" />
</view>
<image mode="aspectFill" src={{item}} />
</view>
<view class="upload" a:if="{{imageUrl.length >= maxCount ? false:true}}">
<view class="add" catchTap="handleSelectImage">
<am-icon type="AddOutline" color="#333333" size="small" />
</view>
</view>
</view>
upload-image.ts
Component({
mixins: [],
data: {
imageUrl: [], // 图片的url地址
maxCount: 1, //上传图片数量
action: 'xxxxxx', // '上传文件的服务器地址'
},
props: {
maxCount: 1,
onUpload: (image, imageArr) => {},
onDelete: (image, imageArr) => {},
value: [],
action: '',
},
didMount() {
const maxCount = this.props?.maxCount || 1
const value = this.props?.value || []
const action =
this.props?.action || this.data.action
this.setData({
maxCount,
imageUrl: value,
action,
})
},
methods: {
handleSelectImage() {
my.chooseImage({
sourceType: ['camera', 'album'], //文件来源
count: 1,
success: (res) => {
const path = res.apFilePaths[0]
const DeviceId = my.getStorageSync({ key: 'DeviceId' }).data
const ACCESS_TOKEN = my.getStorageSync({ key: '__AT__' }).data
const { account } = my.getStorageSync({ key: 'userinfo' }).data as any
const { action } = this.data
my.uploadFile({
url: action,
fileType: 'image',
fileName: 'file',
filePath: path,
//设置请求头信息
header: {
DeviceId: DeviceId,
uname: account,
System: 'xxxx',
},
success: (res) => {
const value = JSON.parse(res.data)
if (value?.code == 200) {
const { imageUrl } = this.data
const newImageUrl = imageUrl.concat(value?.data) // value?.data 是后端接口返回的图片url地址
this.setData({
imageUrl: newImageUrl,
})
this.props.onUpload(value?.data, newImageUrl)
} else {
my.showToast({
content: value?.msg || '上传失败',
})
}
},
fail: (err) => {
my.showToast({
content: '上传失败',
})
const { imageUrl } = this.data
const newImageUrl = imageUrl.concat([])
this.setData({
imageUrl: newImageUrl,
})
},
})
},
})
},
handleDelete(e) {
const { index } = e.currentTarget.dataset
const { imageUrl } = this.data
const newData = imageUrl.filter((i) => i !== index)
this.setData({
imageUrl: newData,
})
this.props.onDelete(index, newData)
},
},
})
upload-image.less
.upload-container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
.upload {
width: 80px;
height: 80px;
background: #f5f5f5;
border-radius: 4px;
display: flex;
justify-content: center;
align-items: center;
position: relative;
margin-right: 8px;
margin-bottom: 8px;
.add {
position: absolute;
margin: auto;
}
.clear {
position: absolute;
top: 0;
right: 0;
margin-top: -6px;
margin-right: -6px;
}
> image {
width: 100%;
height: 100%;
border-radius: 4px;
background: #fff;
}
.loading {
position: absolute;
margin: auto;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
.amd-loading-spin-container {
width: 100%;
height: 100%;
}
.amd-loading-spin-text {
color: #ffff;
}
}
}
}
upload-image.json
{
"component": true,
"usingComponents": {
"am-icon": "antd-mini/es/Icon/index",
"loading": "antd-mini/es/Loading/index"
}
}
(二)、在页面中 引用组件
pageX.axml
<upload-image maxCount="{{9}}" onDelete="handleImageDelete" onUpload="hanldeImageUpload" value="{{imageValue}}" />
<view onTap="handleFinish">上传</view>
pageX.json
{
"defaultTitle": "上传图片",
"usingComponents": {
"upload-image":"/components/upload-image/upload-image" // 组件的路径
}
}
pageX.ts
data:{
imageValue:[]
}
async handleImageDelete(file, fileList) {
//删除图片
this.setData({
imageValue: fileList,
})
},
hanldeImageUpload(file, fileList) {
//上传图片
this.setData({
imageValue: fileList,
})
},
handleFinish(){
console.log(this.imgValue)
}