208 lines
4.2 KiB
Vue
208 lines
4.2 KiB
Vue
<template>
|
||
<view class="video-upload">
|
||
<view class="fileList" v-for="(item,index) in list" :key="index">
|
||
<video class="video" :id="item.videoId" @fullscreenchange="fullscreenchange" :show-fullscreen-btn="true"
|
||
:poster="item.url" :src="item.url">
|
||
<!-- cover-image 需要放到video组建里面 -->
|
||
<cover-image src="https://sancangshop.oss-cn-beijing.aliyuncs.com/frog/close.png" v-if="deletable" class="icon" @click.stop="deleteItem(index)">
|
||
</cover-image>
|
||
</video>
|
||
</view>
|
||
<view v-if="maxCount>list.length" class="uploadBox" @click="chooseVideo">
|
||
<u-icon class="icon" size="26" color="#D3D4D6" name="play-circle-fill"></u-icon>
|
||
</view>
|
||
<u-toast ref="uToast"></u-toast>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
export default {
|
||
props: {
|
||
value: {
|
||
type: String,
|
||
default: ""
|
||
},
|
||
//单个文件上传大小(M)
|
||
maxSize: {
|
||
type: Number,
|
||
default: 1 //1M
|
||
},
|
||
//上传文件数量
|
||
maxCount: { // 限制数量
|
||
type: Number,
|
||
default: 2
|
||
},
|
||
//是否显示删除按钮
|
||
deletable: {
|
||
type: Boolean,
|
||
default: true
|
||
},
|
||
//视频来源
|
||
sourceType: {
|
||
type: Array,
|
||
default: () => {
|
||
return ["album", "camera"];
|
||
}
|
||
}
|
||
},
|
||
name: "video-upload",
|
||
data() {
|
||
return {
|
||
list: [],
|
||
VideoContext: null,
|
||
state: false,
|
||
videoId: null
|
||
};
|
||
},
|
||
watch: {
|
||
value: {
|
||
handler(val) {
|
||
if (val) {
|
||
this.list = val.split(',').map(url => {
|
||
return {
|
||
url: uni.$u.http.config.baseURL + url,
|
||
width: "100%",
|
||
videoId: Date.now() + Math.ceil(Math.random() * 10000000) + ''
|
||
}
|
||
})
|
||
}
|
||
}
|
||
},
|
||
state(state, oldValue) {
|
||
if (!state) {
|
||
this.VideoContext.pause();
|
||
} else {
|
||
this.VideoContext.play();
|
||
this.$nextTick(() => {
|
||
this.VideoContext.requestFullScreen();
|
||
});
|
||
}
|
||
},
|
||
list: {
|
||
handler(val) {
|
||
this.emits()
|
||
},
|
||
deep: true
|
||
}
|
||
},
|
||
methods: {
|
||
//文件上传接口
|
||
uploadFile(url) {
|
||
//这是用promise封装异步请求
|
||
return new Promise((resolve, reject) => {
|
||
uni.$u.http.upload('/common/upload', {
|
||
filePath: url,
|
||
name: 'file',
|
||
timeout: 60000 //超时时间设置为1分钟,防止时间过短无法上传
|
||
}).then(res => {
|
||
resolve(res);
|
||
}).catch(error => {
|
||
reject(error)
|
||
});
|
||
});
|
||
},
|
||
chooseVideo() {
|
||
uni.chooseVideo({
|
||
sourceType: this.sourceType,
|
||
compressed: true,
|
||
success: async (file) => {
|
||
if (file.size > this.maxSize * 1024 * 1224) {
|
||
this.$refs.uToast.show({
|
||
type: 'error',
|
||
icon: false,
|
||
title: '视频超过大小',
|
||
message: "视频大小不超过" + this.maxSize + 'M',
|
||
});
|
||
return;
|
||
}
|
||
const {
|
||
url
|
||
} = await this.uploadFile(file.tempFilePath)
|
||
this.list.push({
|
||
url: url,
|
||
width: '100%',
|
||
videoId: Date.now() + Math.ceil(Math.random() * 10000000) + ''
|
||
})
|
||
}
|
||
})
|
||
},
|
||
fullscreenchange(e) {
|
||
this.state = e.detail.fullScreen;
|
||
},
|
||
changeState(id) {
|
||
this.VideoContext = uni.createVideoContext(id)
|
||
this.state = true
|
||
},
|
||
//删除元素
|
||
deleteItem(index) {
|
||
this.list[index].width = "0"
|
||
setTimeout(() => {
|
||
this.list.splice(index, 1)
|
||
}, 10)
|
||
},
|
||
emits() {
|
||
const {
|
||
list
|
||
} = this
|
||
const imgUrls = list.map((item) => {
|
||
const i = item.url.indexOf('/profile/upload')
|
||
return item.url.slice(i)
|
||
}).join(',')
|
||
this.$emit('input', imgUrls)
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss">
|
||
.video-upload {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
|
||
.fileList {
|
||
width: 320rpx;
|
||
height: 200rpx;
|
||
border-radius: 5rpx;
|
||
overflow: hidden;
|
||
position: relative;
|
||
margin-right: 20rpx;
|
||
margin-bottom: 20rpx;
|
||
|
||
.video {
|
||
height: 100%;
|
||
width: 100%;
|
||
}
|
||
|
||
.icon {
|
||
width: 40rpx;
|
||
height: 40rpx;
|
||
color: red;
|
||
position: absolute;
|
||
right: 0rpx;
|
||
top: 0rpx;
|
||
z-index: 200;
|
||
overflow: hidden;
|
||
|
||
.close {
|
||
position: absolute;
|
||
left: 10rpx;
|
||
bottom: 10rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
.uploadBox {
|
||
width: 320rpx;
|
||
height: 200rpx;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
background-color: #F4F5F7;
|
||
border-radius: 10rpx;
|
||
|
||
.icon {
|
||
margin: auto;
|
||
}
|
||
}
|
||
}
|
||
</style> |