参与的微信小程序项目需要一个上传视频的功能,最开始的想法是从与Taro框架搭配的Taro UI库中寻找一个视频上传组件,但是在浏览了Taro UI库后,只发现了ImagePicker 图片选择器,所以决定自己封装一个视频上传组件VideoUpLoad。
话不多说,直接上代码:
index.js
class VideoUpLoad extends Component {
constructor(props) {
super(props);
this.state = {
src: [], //视频url
srcList: [], //视频的fileName
};
}
chooseVideo =() => { //视频上传,并判断最大数量
const { type, onChange, checkLoading} = this.props;
const {src} = this.state;
if(src.length >= 5) {
Taro.showToast({
title: '上传数量已达最高',
duration: 2000,
icon: 'error',
mask: false,
})
return;
}
var _this = this;
Taro.chooseVideo({
count: 1,
mediaType: ['video'],
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success(res) {
Taro.showLoading({
title:'视频上传中'
})
Taro.uploadFile({
url: `${baseUrl}/admin/sys-file/upload?type=${type}`,
filePath :res.tempFilePath,
name: 'file',
fileType: "mp4",
header: {
'content-type': 'multipart/form-data',
'Authorization': tokenHandler.getSessionByKey("authorization") //存在Storage里的token
},
formData: {
type: type,
},
complete:(response) => {
Taro.hideLoading()
const data = JSON.parse(response.data);
const tempFilePathsMp3 = _this.state.src;
const mp3List = _this.state.srcList;
tempFilePathsMp3.push(res.tempFilePath);
mp3List.push(data.data.fileName);
onChange(mp3List)
Taro.showToast({
title: '上传成功',
duration: 2000,
icon: 'success',
mask: false,
})
_this.setState({
src: tempFilePathsMp3,
srcList: mp3List
})
}
})
}
})
};
deleteVideo =(index) => { //删除上传了的视频
const { checkLoading, onChange} = this.props;
const _this = this;
const srcs = _this.state.src;
const srcList = _this.state.srcList;
const removeName = srcList[index];
wx.showModal({
title: '提示',
content: '确认要删除该视频吗?',
success: function (res) {
if (res.confirm) {
if(typeof checkLoading === 'function') checkLoading(true)
Taro.request({
url: `${baseUrl}/admin/sys-file/del?fileName=${removeName}`, // 请求的URL
method: 'DELETE', // 请求方法为DELETE
header: {
'Authorization': tokenHandler.getSessionByKey("authorization"),
"Content-Type": "application/json",
"Accept": "application/json"
}, // 请求头
success(res) {
Taro.showToast({
title: '删除成功',
duration: 2000,
icon: 'success',
mask: false,
})
srcs.splice(index, 1);
srcList.splice(index, 1);
onChange(srcList);
_this.setState({
src: srcs
})
},
fail(err) {
// 请求失败的处理逻辑
console.error('删除失败', err);
}
})
} else if (res.cancel) {
console.log("点击取消了");
return false
}
}
})
}
render() {
const {videoList} = this.props; //父组件传过来已经上传过了的视频
const { src } = this.state;
const videoLists = [...videoList, ...src];
return (
<View className="img-list">
{videoLists.map((item, index) => {
return <View className="upload-video" key={index}>
<Video src={item.url} className="img-li"></Video>
<Image className="icon-deletes at-icon at-icon-close" onClick={() => this.deleteVideo(index)}></Image>
</View>
})}
<View className='upload-div' onClick={this.chooseVideo}>
<View className='upload-div-view'>
<AtIcon value='upload' size='50' />
<View style={{fontSize: '24rpx'}}>选择视频</View>
</View>
</View>
</View>
);
}
}
index.less
/* 上传的图片 */
.img-list {
display: flex;
padding: 10rpx;
flex-wrap: wrap;
}
.img-li {
width: 150rpx;
height: 150rpx;
margin-right: 39rpx;
margin-bottom: 23rpx;
}
.img-li:first-child {
margin-right: 0;
}
.img-li image {
width: 100%;
height: 100%;
}
.icon-delete {
width: 28rpx !important;
height: 28rpx !important;
position: relative;
float: right;
margin-top: -229rpx;
margin-right: -15rpx;
z-index: 99;
}
.icon-deletes {
width: 50rpx !important;
height: 50rpx !important;
position: relative;
float: right;
margin-left: -36rpx;
margin-right: 29rpx;
z-index: 99;
color: rgb(177, 173, 173);
// background-color: red;
}
.content-input-z {
display: flex;
align-items: center;
justify-content: space-between;
font-size: 24rpx;
color: #999999;
}
.content-input-z {
margin-top: 31rpx;
}
.content-input-z view image {
width: 32rpx;
height: 31rpx;
margin-right: 11rpx;
}
.content-input-z view {
display: flex;
align-items: center;
}
.upload-div {
width: 150rpx;
height: 150rpx;
position: relative;
border: 1px #d6e4ef solid;
transition: background-color 0.2s;
}
.upload-div:active {
background-color: #bfbdbd;
}
.upload-div-view {
position: absolute;
top: 50%;
left: 50%;
text-align: center;
transform: translate(-50%, -50%);
}
组件效果: