赞
踩
引入:
之前写过一篇关于 uview 1.x 版本上传照片 的文章,但是发现如果是在微信小程序的项目中嵌入 h5 的模块,这个 h5 的项目使用 u-upload 的话,图片上传功能在电脑上正常,但是在手机的小程序上测试就不会生效,点击上传加号按钮毫无反应。
解决方法:
现在最终的解决方法是,使用 uniapp 的 uni.chooseImage
来选择照片,使用 uni.uploadFile
来上传图片,其他所有的样式和逻辑都自己来实现,最终的效果长这样:
代码与解析:
单独写一个组件,先实现样式:
<template> <view class="meeting-image"> <view class="title"> <text></text> <!-- 展示图片张数 --> <text style="color: #a1a1a1;">({{ list.length }}/9)</text> </view> <view class="img_wrap flex-row flex-justify-between"> <view class="img_box" v-for="(item, index) in list" :key="index"> <!-- 展示上传之后的图片 --> <image :src="item.imgUrl" class="pic" mode="aspectFill" @click="previewImage(index)" /> <!-- 删除图标 --> <!-- 这里的删除图标叉叉是用的在线网址,$public 是挂载在原型上的,可以自定义 --> <image :src="`${$public()}/project-meeting/icon_20_close.png`" class="close" @click.stop="handleDeleteImg(index, item)" /> </view> <!-- 上传的方框 --> <view class="upload-box" @click="chooseImg" v-if="list.length !== 9 && isSponsorUserFlag == 1" ></view> </view> <u-toast ref="uToast" /> </view> </template>
.meeting-image { .title { font-size: 32rpx; line-height: 40 rpx; text:nth-of-type(1) { color: #ff3f30; padding-right: 4rpx; } text:nth-of-type(3) { padding-left: 12rpx; color: #cccccc; } } .img_wrap { flex-wrap: wrap; &::after { width: calc((100% - 40rpx) / 3); display: block; content: ''; } .img_box { margin-top: 20rpx; position: relative; width: calc((100% - 40rpx) / 3); height: 220rpx; .pic { width: 100%; height: 100%; object-fit: cover; border-radius: 14rpx; } .close { position: absolute; top: -8rpx; right: -8rpx; width: 40rpx; height: 40rpx; } } .upload-box { position: relative; width: calc((100% - 40rpx) / 3); height: 220rpx; border: 1px solid #e5e5e5; box-sizing: border-box; position: relative; border-radius: 14rpx; margin-top: 20rpx; &::after { display: block; content: ''; width: 1px; height: 96rpx; background-color: #e5e5e5; position: absolute; left: 105rpx; top: 50rpx; } &::before { display: block; content: ''; width: 96rpx; height: 1px; background-color: #e5e5e5; position: absolute; right: 60rpx; top: 100rpx; } } } }
js 逻辑部分,我这里后端提供的 api 有上传(查询文件地址),即代码中的 previewUrl
,删除的实现方法是在本地进行的,是对数组进行 splice 之后,再将最新的图片数组保存进大数组一次,最后再进行上传,注释写的很详细,方便以后回顾查看。
简单解释:
chooseImg
是最先执行的函数,即点击上传按钮时执行,进来判断是不是数量超过了 9 张,没超过就往下走;
使用 uni.chooseImage
进行图片选择功能,配置相应参数和值,选择成功,走到 then 的成功回调里,回显照片,此时调接口 previewUrl
来上传获取图片id;
然后将图片保存进数组中
<script> import { BASE_URL } from '@/pages/workTable/utils/constant' import { previewUrl } from '@/pages/workTable/utils/api.js' export default { name: 'meeting-image', // 接收参数 props: { fileList: { type: Array, default: [] }, // 用于该页面有很多项,而每一项都需要传一组图片的页面 subItem: { }, // 用于只传一组图片的页面 picListArr: { }, picList: { } }, data() { return { list: [], count: 9, } }, computed: {}, methods: { // 预览功能暂时有问题 previewImage(index) { console.log('预览', this.list.map(el => el.imgUrl)); uni.previewImage({ current: index, urls: this.list.map(el => el.imgUrl) }) }, // 点击上传按钮触发 chooseImg() { // 如果大于 9 张就不触发底下的 uni.chooseImage if (this.count == 0) { this.$refs.uToast.show({ title: '最多能上传9张照片', duration: 2000 }) return } uni.chooseImage({ // 最多可以选择的图片张数,默认9 count: this.count, // original 原图,compressed 压缩图,默认二者都有 sizeType: ['original', 'compressed'], // album 从相册选图,camera 使用相机,默认二者都有 sourceType: ['album', 'camera'], success: res => { // console.log('res',res); uni.showLoading({ title: '上传中' }) Promise.all( res.tempFilePaths.map(item => { return this.uploadFile({ filePath: item }) }) ) .then(re => { uni.hideLoading() // let fileList = [] re.map((el, index) => { let data = JSON.parse(el.data) // 用于上传成功后照片回显 // console.log('data',data.data); previewUrl(data.data).then(res => { console.log('我要预览图片', res); this.list.push({ fileUrl: data.data, imgUrl: res.data }) setTimeout(() => { console.log('this.list', this.list); this.saveFile(this.list) }, 800) }) }) }) .catch(err => { console.log('err', err); this.$refs.uToast.show({ title: '上传失败', duration: 2000 }) uni.hideLoading() }) }, fail: () => { } }) }, // 上传图片 uploadFile({ filePath }) { return new Promise((resolve, reject) => { uni.uploadFile({ url: `${BASE_URL}/mobilemanage/api/common/upload?typeEnum=IMAGE`, filePath: filePath, name: 'file', header: { 'site3-f-ue': uni.getStorageSync('site3-f-ue') }, formData: { typeEnum: "IMAGE", }, success: res => { console.log('调用上传接口的结果', res); resolve(res) }, fail: error => { reject(error) } }) }) }, // 将图片保存进数组 saveFile(list) { console.log('aaaaaaaaaa', list); // 子组件拿接到的父组件传过来的值,subItem 是每一项的数据,里面有 picList 和 picListArr console.log('父组件传过来的subItem', this.subItem); // 每一项都需要上传照片这种情况才需要用到 subItem if (this.subItem) { console.log('有 subItem 的情况'); let subItem = this.subItem subItem.picList = [] subItem.picListArr = [] list.map(async item => { console.log('bbbbbbbb', item); subItem.picList.push({ fileUrl: item.fileUrl }) console.log('subItem.picList', subItem.picList); }) console.log('subItem.picList', subItem.picList); subItem.picList.map(item => { subItem.picListArr.push(item.fileUrl) }) console.log('subItem.picListArr', subItem.picListArr); } else { console.log('没有subItem的情况', list); // 只需要上传一组图片 let picList = this.picList let picListArr = this.picListArr picList = [] picListArr = [] // console.log('list',list); list.map(async item => { console.log('qqqqqqqqqqqq', item); picList.push({ fileUrl: item.fileUrl }) }) this.$emit('getPicList', picList) console.log('照片列表', picList); } }, // 删除图片 handleDeleteImg(index, item) { this.list.splice(index, 1) this.saveFile(this.list) this.$refs.uToast.show({ title: '删除成功', duration: 2000 }) } }, watch: { // 监视当前图片数组长度,增减张数显示 fileList: { handler: function (value) { this.list = value this.count = 9 - this.list.length }, deep: true, immediate: true } } } </script>
使用的时候,父组件进行调用传值:
import uploadImage from '../components/upload-image'
components: {
uploadImage
},
<upload-image
:fileList="subItem.picList"
:subItem="subItem"
:projectMeetingId="1"
:isSponsorUserFlag="1"
></upload-image>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。