vant 上传视频 预览 组件 (部分安卓机不支持,推荐调用原生方法,自己重写样式,否则会弹出系统自带的文件选择界面,PC端不受影响)

<template>
    <div class="van-uploader">
        <div class="van-uploader__wrapper">
            <div class="van-uploader__preview" v-for="(item, index) in uploadVideoList" :key="index">
                <div class="van-image van-uploader__preview-image">
                    <video style="width:80px;height:80px;object-fit:cover;" :src="item" ></video>
                    <div role="button" class="van-uploader__preview-delete van-uploader__preview-delete--shadow"
                        :tabindex="index" aria-label="删除" @click="delBtn(index)">
                        <i class="van-badge__wrapper van-icon van-icon-cross van-uploader__preview-delete-icon">
                        </i>
                    </div>
                </div>
            </div>
            <div class="van-uploader__upload" v-show="uploadVideoList.length < 3">
                <van-uploader accept="video/*" :after-read="beforeRead" :max-size="50 * 1024 * 1024"
                    @oversize="onOversize">
                </van-uploader>
            </div>
        </div>
    </div>
</template>

<script lang="ts" setup>
import { Toast } from 'vant';
import { ref } from 'vue'

const tagList = ref([])
const uploadTitle = ref('')
const currentTag = ref(null)
const tagId = ref(null)
const fileIdArr = ref([])
const uploadVideoList = ref<any>([]) // 选中的上传视频列表
const videoSrc = ref('')   // 选中的视频的src,用来显示视频
const uploadDocList = ref<any>([]) // 选中的上传文档列表
const uploadAudioList = ref<any>([]) // 选中的上传音频列表
const uploadPicList = ref([]) // 选中的上传图片列表
const picSrc = ref('')  // 选中的图片的src,用来显示图片缩略图
let tmp = ref<any>([])
const fileTypes = ['video/mp4']

// 文件选中后先提交给后台,后台根据选中的文件,返回数组(这一业务根据后台而定)
const beforeRead = (file) => {
    console.log(file, "111111111")
    if (!fileTypes.includes(file.file.type)) {
        Toast('仅可上传视频')
        return false
    }

    let formData = new FormData(); // 为上传文件定义一个formData对象
    let config = {
        headers: {
            'Content-Type': 'multipart/form-data'
        }
    };
    // let uploadUrl = URL.createObjectURL(file) as any; // 将选中的上传文件转化为二进制文件,显示在页面上
    uploadVideoList.value.push(file.content);
    // console.log(uploadVideoList.value, "2222222222")
    // videoSrc.value = file.content;
    // console.log(videoSrc.value, "333333333")
    // 这里使用foreach是为了将选中的多个文件都添加进定义的formdata变量中
    // uploadVideoList.value.forEach(item => {
    //     console.log(item,'4444444')
    //     formData.append(item.name, item)
    // })



    // formData.append(file.name, file); // 单个文件上传时可以这么写,上面的foreach就可以删掉
    // this.$api.post(uploadFile, formData, config).then(res => {
    //   this.fileIdArr = res.data.data;  // 把選中的文件傳送給後台
    // }).catch(err => {
    //   Toast('文件上傳失敗!')
    // })
}
// 删除待上传的文件
const delBtn = (index) => {
    // 先判断当前的选中的索引是否是在有效范围中,如果不是则跳出方法 
    if (isNaN(index) || index >= uploadVideoList.value.length) {
        return false;
    }
    tmp = [];
    // 将没被选中的上传文件存放进一个临时数组中
    for (let i = 0; i < uploadVideoList.value.length; i++) {
        if (uploadVideoList.value[i] !== uploadVideoList.value[index]) {
            tmp.push(uploadVideoList.value[i]);
        }
    }
    // 存放当前未被选中的上传文件
    uploadVideoList.value = tmp;

}
const doSubmit = () => {
    let params = {
        classify: tagId.value,    // 针对视频资源时对应的分类id
        file: fileIdArr.value,  // 选择完文件后,调用uploadFile这个接口,后端返回的数组
        resourceColumnId: JSON.parse('视频'),  // 资源栏目id(视频、图片、音频、文档)
        title: uploadTitle.value  // 上传时填写的标题
    };
    // this.$api.post(addResources, params).then(res => {
    //   if(res.data.code === 1001){
    //     if(columnName === '视频'){
    //       this.$router.push({name: 'myVideo'});
    //     }else {
    //       this.$router.push({name: 'myResourceClassify'});
    //     }
    //   }
    // }).catch(err => {
    //   console.log(err)
    // })
}

const onOversize = (file) => {
    Toast("支持MP4格式的视频,每个视频最大50M");
    return false
}

</script>
<style lang="scss" scoped>
.upload {
    box-sizing: border-box;
}

.forPreview_video {
    position: relative;

    /*background: rgba(0,0,0,.7);*/
    video {
        width: 95%;
        max-height: 430px;
    }

    .delte {
        position: absolute;
        right: 0;
        bottom: 0;
    }
}

.forPreview_doc,
.forPreview_audio {
    display: flex;
    margin-bottom: 10px;
    align-items: center;

    img {
        width: 56px;
        height: 56px;
        margin-right: 20px;
    }

    span:nth-of-type(1) {
        flex: 1;
    }

    span:nth-of-type(2) {
        margin-right: 20px;
    }
}

.forPreview_pic {
    display: flex;
    align-items: flex-end;

    img {
        width: 160px;
        height: 160px;
    }
}

.diy-detail {
    width: 100%;
    overflow: hidden;

    .btn {
        span {
            margin-bottom: 10px;
        }
    }

    .van-cell {
        background-color: #F0F0F0;
        border-radius: 35px;
        font-size: 26px;
        height: 69px;
        line-height: 69px;
        padding: 0 22px;
        color: #999;
    }

    .van-hairline--top-bottom::after,
    .van-hairline-unset--top-bottom::after {
        border-width: 0;
    }

    p {
        height: 64px;
        line-height: 64px;
        font-size: 32px;
        color: #333;
        position: relative;
        padding-left: 16px;
    }

    p::before {
        position: absolute;
        top: 0;
        left: 0;
        content: '*';
        color: #FF0000;
    }

    span {
        display: inline-block;
        width: 157px;
        background: #F0F0F0;
        border-radius: 35px;
        color: #999;
        font-size: 26px;
        padding: 14px 18px;
        margin-right: 28px;
        text-align: center;
    }

    .active {
        color: #fff;
        background: linear-gradient(to right, #FD5130, #FA6C34);
    }
}

.diy-submit {
    position: fixed;
    height: 150px;
    width: 90%;
    bottom: 0;
    background: #fff;

    .van-button {
        width: 100%;
        height: 90px;
        border-radius: 45px;
        font-size: 36px;
        color: #fff;
        background: linear-gradient(to right, #FD5130, #FA6C34);
        top: 50%;
        transform: translate(0, -50%);
    }

    .van-button--default {
        border: none;
    }
}

.van-uploader__preview {
    margin: 0 10px;
}
</style>

类似这样的界面

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值