支付宝小程序 | 上传图片组件(添加默认样式以及自定义上传样式)

使用my.uploadFile、 my.chooseImage 的方式实现图片上传

注意: 使用该方式上传文件,后端也需要参照官方文档进行修改

https://opendocs.alipay.com/mini/api/kmq4hc

一、展示效果

默认上传

demo4.gif

自定义上传

demo5.gif

二、上代码

(一)、上传组件

image.png

<view class="custom-upload-container"> <view a:for="{{imageUrl}}" class="custom-upload images-show"> <view class="clear" catchTap="handleDelete" data-url="{{item}}"> <am-icon type="CloseCircleFill" color="#333333" size="x-small" /> </view> <view a:if="{{item.status == 'fail' ? true : false}}" class="loading"> <loading type="spin" size="small" text="上传中..." loading="{{true}}" /> </view> <image mode="aspectFill" src={{item}} catchTap="hanldeImageLook" data-url="{{item}}" data-index="{{index}}" /> </view> <view a:if="{{imageUrl.length < maxCount && imageUrl.length > 0 ? true:false}}" class="custom-upload " > <view class="add" catchTap="handleSelectImage"> <am-icon type="AddOutline" color="#333333" size="small" /> </view> </view> <view catchTap="handleSelectImage" style="width:100%"> <slot a:if="{{ imageUrl.length == 0 ?true:false }}"> <view class="default-upload"> <am-icon type="AddOutline" color="#333333" size="small" /> </view> </slot> </view> </view>

upload-image.ts

Component({ mixins: [], data: { imageUrl: [], maxCount: 1, action: '', //上传的url地址 }, 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 || 'xxxxxxxx' this.setData({ maxCount, imageUrl: value, action, }) }, didUpdate() {}, didUnmount() {}, methods: { handleSelectImage() { const { imageUrl, maxCount } = this.data if (imageUrl.length == maxCount) { my.showToast({ content: `最多上传${maxCount}张图片`, }) return } 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 const SYSTEM_ID = (my.getStorageSync({ key: 'SyStemId' }).data as string) my.uploadFile({ url: action, fileType: 'image', fileName: 'file', filePath: path, name: 'file', //请求头信息 header: { DeviceId: DeviceId, uname: account, System: SYSTEM_ID, }, success: (res) => { const value = JSON.parse(res.data) if (value?.code == 200) { const { imageUrl } = this.data const newImageUrl = imageUrl.concat(value?.data) 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, status: 'fail', }) }, }) }, }) }, handleDelete(e) { const { url } = e.currentTarget.dataset const { imageUrl } = this.data const newData = imageUrl.filter((i) => i !== url) this.setData({ imageUrl: newData, }) this.props.onDelete(index, newData) }, hanldeImageLook(e) { const { imageUrl } = this.data const { index } = e.currentTarget.dataset my.previewImage({ current: index, // 当前显示图片 urls: imageUrl, success: (res) => { console.log('debug----res', res) }, fail: (error) => { console.log('debug----error', error) }, }) }, }, })

upload-image.less

.custom-upload-container { display: flex; flex-direction: row; flex-wrap: wrap; background: #ffffff; padding: 16px; border-radius: 8px; .custom-upload, .images-show { width: 80px; height: 80px; background: #ffffff; border: 1px dashed #979797; border-radius: 6px; display: flex; justify-content: center; align-items: center; position: relative; margin-right: 30px; .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; } } } .custom-upload:nth-of-type(3n) { margin-right: 0px; } .images-show { border: none; } .default-upload { width: 100%; height: 80px; border-radius: 4px; border: 1px dashed #979797; display: flex; justify-content: center; align-items: center; background: #ffffff; } }

upload-image.json

{ "component": true, "usingComponents": { "am-icon": "antd-mini/es/Icon/index", "loading": "antd-mini/es/Loading/index" } }

(二)、在页面中引用组件

pageX.axml

//自定义上传样式 <upload-image maxCount="{{imgCount}}" value="{{imgValue}}" onUpload="handleUpload" onDelete="handleDelete" > <view class="uplload-images"> <text class="tip1">添加图片(非必传)</text> <text class="tip2">最多可以添加{{imgCount}}张图片</text> </view> </upload-image> //默认样式 <upload-image maxCount="{{imgCount}}" value="{{imgValue}}" onUpload="handleUpload" onDelete="handleDelete" > </upload-image>

pageX.less

.uplload-images { width: 100%; height: 80px; background: #ffffff; border-radius: 8px; display: flex; flex-direction: column; justify-content: center; align-items: center; .tip1 { font-size: 14px; font-family: PingFangSC-Regular, PingFang SC; font-weight: 400; color: #333333; line-height: 20px; } .tip2 { font-size: 12px; font-family: PingFangSC-Regular, PingFang SC; font-weight: 400; color: #999999; line-height: 16px; margin-top: 8px; } }

pageX.json

{ "defaultTitle": "上传图片", "usingComponents": { "upload-image":"/components/upload-image/upload-image" // 组件的路径 } }

pageX.ts

data:{ imgValue:[], imgCount:3, }, handleUpload(file, fileList) { this.setData({ imgValue: fileList, }) }, handleDelete(file, fileList) { const arr = [] let { deleteImage } = this.data arr.push(file) const newImage = deleteImage.concat(arr) this.setData({ imgValue: fileList, deleteImage: newImage, }) },

__EOF__

本文作者杨芋可可
本文链接https://www.cnblogs.com/yangyukeke/p/17432831.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   杨芋可可  阅读(359)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示