上需求,上传图片视频时:
1:让用户自行选择照片或者视频,更方便、更精确上传,如下图
2:上传图片限制最多6张,视频最多一个
3:上传了图片就隐藏掉选择视频的选项,上传了一个视频就不能继续上传其他图片或者视频
4:图片预览、视频预览
小程序UI用到的是colorUI,提取出来该部分代码如下
WSML
// firstType 为控制显示视频还是图片
<view class="cu-bar bg-white margin-top">
<view class="action">
图片/视频上传
</view>
<view class="action">
{{media.length}}/6
</view>
</view>
<view class="cu-form-group">
<view class="grid col-4 grid-square flex-sub" >
<view class="bg-img mediaBox" wx:for="{{media}}" wx:key="index" >
<view wx:if='{{ firstType == 1}}' data-src='{{item}}' bindtap="ViewMedia">
<image src='{{item}}' mode='aspectFill' ></image>
<view class="cu-tag bg-red" catchtap="DelMedia" data-index="{{index}}">
<text class="cuIcon-close"></text>
</view>
</view>
<view wx:if='{{ firstType == 2}}' data-src='{{item}}' bindtap="ViewVideo">
<image src="../../../images/bf.png" id="playImg" ></image>
<video src='{{item}}' id="uploadVideo" object-fit='fill' controls='{{false}}'></video>
<view class="cu-tag bg-red" catchtap="DelMedia" data-index="{{index}}">
<text class="cuIcon-close"></text>
</view>
</view>
</view>
<view class="solids" bindtap="chooseFile" wx:if='{{media.length <= 0}}'>
<text class="cuIcon-cameraadd"></text>
</view>
<view class="solids" bindtap="chooseFile" wx:if="{{media.length > 0 && firstType == 1}}">
<text class="cuIcon-cameraadd"></text>
</view>
</view>
</view>
JS
import config from '../../../utils/config.js'
const app = getApp()
Page({
/**
* 页面的初始数据
*/
data: {
firstType: 1,
media: [] // 上传的图片/视频
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {},
// 图片/视频上传
chooseFile(){
var that = this
var itemList = ['拍摄照片/视频', '从相册选择照片','从相册选择视频']
if (this.data.media.length <= 0) {
} else if (this.data.media.length > 0 && this.data.firstType == 1) {
itemList = ['拍摄照片', '从相册选择照片']
}
wx.showActionSheet({
itemList: itemList,
success (res) {
if (!res.cancel) {
if (res.tapIndex == 0) {
that.ChooseMedia(1,'camera') // 拍摄照片/视频
} else if (res.tapIndex == 1) {
that.ChooseImage() // 从相册选择照片
} else if (res.tapIndex == 2) {
that.ChooseMedia(2,'album') // 从相册选择视频
}
}
},
fail (res) {
console.log(res.errMsg)
}
})
},
// 选择视频
ChooseMedia(mType,sType) {
var firstType, that = this
var mediaType = mType == 1?['image','video']:['video'] // 可选择媒体类型
wx.chooseMedia({
count: 1, // 可选个数
mediaType: mediaType,
sourceType: [sType], // 可以指定是原图还是压缩图,默认二者都有
maxDuration: 15, // 视频最大时长
camera: 'back', // 摄像头方向
success: (res) => {
if (res.type == "image") {
firstType = 1
} else {
firstType = 2
}
const tempFiles = res.tempFiles
tempFiles.map((v,i) => {
wx.showLoading({title: '上传中...',mask: true})
console.log(res.type)
console.log(tempFiles[i].tempFilePath)
wx.uploadFile({
url: `${config.api}/api/v1/file`,
header: {
"Content-Type": "multipart/form-data",
"Authorization": 'Bearer ' + app.storage.getStorSync('access_token') // 本项目接口需求 可忽略
},
filePath: tempFiles[i].tempFilePath,
name: 'file', // 后台传参参数名
formData: {type: res.type},
success(res) {
console.log(res)
if (res.statusCode != 200) {
wx.hideLoading()
return
}
var arr = that.data.media;
arr.push(JSON.parse(res.data).data.url) // 转译JSON字符串 并存储
that.setData({
media: arr,
firstType: firstType
});
if (tempFiles.length === i + 1) {
wx.hideLoading()
}
},
fail:function (err){
console.log(err)
}
})
})
}
});
},
// 选择图片
ChooseImage() {
var that = this
wx.chooseImage({
count: 6 - this.data.media.length,
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
sourceType: ['album'], // 从相册选择
success: (res) => {
const tempFilePaths = res.tempFilePaths
tempFilePaths.map((v,i) => {
wx.showLoading({title: '上传中...',mask: true})
wx.uploadFile({
url: `${config.api}/api/v1/file`,
header: {
"Content-Type": "multipart/form-data",
"Authorization": 'Bearer ' + app.storage.getStorSync('access_token') // 本项目接口需求 可忽略
},
filePath: tempFilePaths[i],
name: 'file',
formData: {type: 'image'},
success(res) {
console.log(res)
if (res.statusCode != 200) {
wx.hideLoading()
return
}
var arr = that.data.media;
arr.push(JSON.parse(res.data).data.url)
that.setData({
media: arr,
firstType: 1
});
if (tempFilePaths.length === i + 1) {
wx.hideLoading()
}
},
fail:function (err){
console.log(err)
}
})
})
}
});
},
// 图片预览
ViewMedia(e) {
wx.previewImage({
urls: this.data.media,
current: e.currentTarget.dataset.src
});
},
// 视频预览
ViewVideo(e) {
var src = e.currentTarget.dataset.src
app.storage.setStorSync('videoUrl',src)
wx.navigateTo({
url: '/pages/videoView/index',
})
},
// 删除上传内容
DelMedia(e) {
wx.showModal({
title: '温馨提示',
content: '确定要删除该内容吗?',
cancelText: '再看看',
confirmText: '删除',
success: res => {
if (res.confirm) {
this.data.media.splice(e.currentTarget.dataset.index, 1);
this.setData({
media: this.data.media
})
}
}
})
}
})
注意:
1:预览 图片预览小程序有API,可以直接使用;视频我好像没有找到,所以就写了个页面来跳转播放视频,弹窗不适合,因为用户进行返回操作的时候,不是隐藏视频而是跳转到了上一个页面,所以体验不太好吗,就写了个专门播放视频的页面,也方便控制样式
2:mediaType 更具需求可以自行动态设置
3:uploadFile 可以自行封装,这里为了简便就没封装了
4:返回值 注意chooseImage
与chooseMedia
返回值结构的区别