插件窝 干货文章 uniapp小程序的图片(视频)上传的组件封装方法

uniapp小程序的图片(视频)上传的组件封装方法

图片 上传 gt lt 1036    来源:    2024-10-18

最近在做小程序,最后想试试新不同的技术,所以选择了用uniapp做小程序。

要求实现多张图片的上传 ,可以限制图片上传的数量,图片预览,多次使用对图片的上传顺序排序

<template>
    <view>
        <view class="upload">
            <!-- 对视频或者图片进行循环 -->
            <block v-for="(upload,index) in uploads" :key="index">
                <view class="uplode-file">
                    <!--  判断是图片还是视频 如果是视频通过 image 进行展示 -->
                    <image v-if="types == 'image'" class="uploade-img" :src="upload" :data-src="upload" @tap="previewImage"></image>
                    <!-- 用于取消的图片 -->
                    <image v-if="types == 'image'" class="clear-one-icon" :src="clearIcon" @tap="delImage(index)"></image>
                    <!-- 如果是视频通过 video进行展示   在视频标签上面添加个图片(删除图片用于取消视频) -->
                    <video v-if="types == 'video'" class="uploade-img" :src="upload" controls>
                        <cover-image v-if="types == 'video'" class="clear-one-icon" :src="clearIcon" @tap="delImage(index)"></cover-image>
                    </video>
                </view>
            </block>
            <!-- 这里是对于没有图片上传之前的样式的展示    如果图片视频的上传的数量大于等于 设定的图片上传的数量 就对不在展示 该样式 这样的话 就不能继续在 上传图片了-->
            <view v-if="uploads.length < uploadCount" :class="uploadIcon ? 'uploader-icon' : 'uploader-input-box'">
                <view v-if="!uploadIcon" class="uploader-input" @tap="chooseUploads"></view>
                <image v-else class="image-cion" :src="uploadIcon" @tap="chooseUploads"></image>
                <view style="height: 40upx; height: 25upx;">
                </view>
                <!-- 这里是对于上传图片的提示 -->
                <p class="ziliao" v-for="(item,index) in text" :key="index"> {{item}}</p>
            </view>
        </view>   
        <!--  提交上传 -->
        <button type="primary" v-if="types == 'image'" @tap="upload" >上传</button>
    </view>
</template>
<script>
    export default{
        //  props 接受传递过来的值
        props: {
            // 上传的图片的提示
            text: {
                type: Array,
                default: function() {
                    return []
                }
            },
            //  用于判断上传的是图片还是视频
            types: {
                type: String,
                default: 'image'
            },
            // 图片上传的路径
            dataList: {
                type: Array,
                default: function() {
                    return []
                }
            },
            //  图标 用于去除已经选中的图片
            clearIcon: {
                type: String,
                default: 'http://img1.imgtn.bdimg.com/it/u=451604666,2295832001&fm=26&gp=0.jpg'
            },
            //  上传的图片的样式  比如说是个相机 还是加号
            uploadIcon: {
                type: String,
                default: ''
            },
            //  需要将图片上传到服务器的 地址
            uploadUrl: {
                type: String,
                default: ''
            },
            //  删除图片的地址
            deleteUrl: {
                type: String,
                default: ''
            },
            //  设置上传图片或视频的数量
            uploadCount: {
                type: Number,
                default: 1
            },
            //上传图片大小 默认3M
            upload_max: {
                type: Number,
                default: 3
            },
            disable:{
                type: Boolean,
                default: true,
            }
        },
        data(){
            return {
                //上传的图片地址
                uploadImages: [],
                //展示的图片地址
                uploads: [],
                // 超出限制数组
                exceeded_list: [],
            }
        },
        mounted(){
            // 对上传图片做个判断
            this.uploads = this.dataList
        },
        methods:{
            previewImage (e) {
                var current = e.target.dataset.src
                uni.previewImage({
                    current: current,
                    urls: this.dataList
                })
            },
            chooseUploads(){
                switch (this.types){
                    case 'image': 
                        uni.chooseImage({
                            count: this.uploadCount - this.uploads.length, //默认9
                            sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
                            sourceType: ['album', 'camera'], //从相册选择
                            success: (res) => {
                                for(let i = 0; i< res.tempFiles.length; i++){
                                    if(Math.ceil(res.tempFiles[i].size / 1024) < this.upload_max * 1024){
                                        this.uploads.push(res.tempFiles[i].path)
                                        this.uploadImages.push(res.tempFiles[i].path)
                                    }else {
                                        this.exceeded_list.push(i === 0 ? 1 : i + 1);
                                        uni.showModal({
                                            title: '提示',
                                            content: `第${[...new Set(this.exceeded_list)].join(',')}张图片超出限制${this.upload_max}MB,已过滤`
                                        });
                                    }
                                }
                            },
                            fail: (err) => {
                                uni.showModal({
                                    // content: JSON.stringify(err)
                                    content: '选择被取消'
                                });
                            }
                        });
                    break;
                    case 'video' :
                        uni.chooseVideo({
                            sourceType: ['camera', 'album'],
                            success: (res) => {
                                if(Math.ceil(res.size / 1024) < this.upload_max * 1024){
                                    this.uploads.push(res.tempFilePath)
                                    uni.uploadFile({
                                        url: this.uploadUrl, //仅为示例,非真实的接口地址
                                        filePath: res.tempFilePath,
                                        name: 'file',
                                        //请求参数
                                        formData: {
                                            'user': 'test'
                                        },
                                        success: (uploadFileRes) => {
                                            this.$emit('successVideo',uploadFileRes)
                                        }
                                    });
                                }else {
                                    uni.showModal({
                                        title: '提示',
                                        content: `第${[...new Set(this.exceeded_list)].join(',')}张视频超出限制${this.upload_max}MB,已过滤`
                                    });
                                }
                            },
                            fail: (err) => {
                                uni.showModal({
                                    // content: JSON.stringify(err)
                                    content: '确认取消?'
                                });
                            }
                        });
                    break;
                }
            },
            delImage(index){
                //第一个是判断app或者h5的 第二个是判断小程序的
                if(this.uploads[index].substring(null,4) !== 'http' || this.uploads[index].substring(null,11) == 'http://tmp/'){
                    this.uploads.splice(index,1)
                    return;
                };
                if(!this.deleteUrl) {
                    uni.showModal({
                        content: '请填写删除接口'
                    });
                    return;
                };
                uni.request({
                    url: this.deleteUrl,
                    method: 'DELETE',
                    data: {
                        image: this.dataList[index]
                    },
                    success: res => {
                        console.log(123456);
                        if(res.data.status == 1) {
                            uni.showToast({
                                title: '删除成功'
                            })
                            this.uploads.splice(index,1)
                        }
                    },
                });
            },
            upload(){
                var _this = this 
                var j = 0 
                if(!this.disable){
                    uni.showModal({
                        content: '请先上传上面的哟'
                    });
                    return;
                }
                if(!this.uploadUrl) {
                    uni.showModal({
                        content: '请填写上传接口'
                    });
                    return;
                };
                if(this.uploadImages.length < 1){
                    uni.showModal({
                        content: '请选择图片'
                    });
                    return;
                }
                if(this.uploadImages.length < this.uploadCount){
                    uni.showModal({
                        content: '请确认上传的数量为' + this.uploadCount + '张'
                    });
                    return;
                }
                for (let i of this.uploadImages) {
                    uni.uploadFile({
                        url: this.uploadUrl, //仅为示例,非真实的接口地址
                        filePath: i,
                        name: 'images[]',
                        //请求参数
                        formData: {
                            'user': 'test'
                        },
                        success: (uploadFileRes) => {
                            this.$emit('successImage',uploadFileRes)
                                j++
                            console.log(j)
                            if( j == _this.uploadCount){
                                this.$emit('successImages',true)
                            }
                        }
                    });
                }
            }
        }
    }
</script>
<style scoped>
    .ziliao{
        margin-top: 15upx;
        text-align: center;
        font-family: MicrosoftYaHei;
            font-size: 20upx;
            font-weight: normal;
            font-stretch: normal;
            line-height: 32upx;
            letter-spacing: 0upx;
            color: #c8c8c8;
    }
    button{
        background-color: #f05a23;
        width: 95%;
    }
    .upload {
        display: flex;
        flex-direction: row;
        flex-wrap: wrap;
    }
    .uplode-file {
        margin: 10upx;
        width: 210upx;
        height: 210upx;
        position: relative;
    }
    .uploade-img {
        display: block;
        width: 210upx;
        height: 210upx;
    }
    .clear-one{
        position: absolute;
        top: -10rpx;
        right: 0;
    }
    .clear-one-icon{
        position: absolute;
        width: 20px;
        height: 20px;
        top: 0;
        right: 0;
        z-index: 9;
    }
    .uploader-input-box {
        position: relative;
        margin:10upx;
        width: 208upx;
        height: 208upx;
        border: 2upx solid #D9D9D9;
    }
    .uploader-input-box:before,
    .uploader-input-box:after {
        content: " ";
        position: absolute;
        top: 50%;
        left: 50%;
        -webkit-transform: translate(-50%, -50%);
        transform: translate(-50%, -50%);
        background-color: #D9D9D9;
    }
    .uploader-input-box:before {
        width: 4upx;
        height: 79upx;
    }
    .uploader-input-box:after {
        width: 79upx;
        height: 4upx;
    }
    .uploader-input-box:active {
        border-color: #999999;
    }
    .uploader-input-box:active:before,
    .uploader-input-box:active:after {
        background-color: #999999;
    }
    .uploader-input {
        position: absolute;
        z-index: 1;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        opacity: 0;
    }
    .uploader-icon{
        position: relative;
        margin:10upx;
        width: 208upx;
        height: 208upx;
    }
    .uploader-icon .image-cion{
        width: 100%;
        height: 100%;
    }
</style>

使用方式:

<easyupload
:text="text"   :dataList="imageList" 
uploadUrl="http://sunshine.createnetwork.cn/api/uploadimage" 
:types="category"
deleteUrl='http://sunshine.createnetwork.cn/api/uploadimage' 
:uploadCount="2" 
disable = true
@successImage="successImage" 
@successVideo="successvideo" 
@successImages="successImages"
class="sxzl"
></easyupload>
<easyupload
:text="text1"
:dataList="imageList" 
uploadUrl="http://sunshine.createnetwork.cn/api/uploadimage" 
:types="category"
deleteUrl='http://sunshine.createnetwork.cn/api/uploadimage' 
:uploadCount="2" 
:disable= 'Drivinglicense'
@successImage="successImage" 
@successVideo="successvideo" 
@successImages="successImages"
class="sxzl"
></easyupload>
<script>
// 导入注册组件 
    import easyupload from "@/common/easy-upload.vue"
    export default {
        components:{
            easyupload
        },
        data() {
            return {
                tx_details:'',
                Drivinglicense: false,
                data:{
                    phone:'',
                    plate_number:'',
                    type_id:'',
                    id_card:[],
                    driving_card:[],
                    name:''
                },
                news:'',
                right_select_num:0,
                text:["身份证正面","身份证反面"],
                text1:["行驶证正页","行驶证副页"],
                imageList: [],
                category: 'image',
                car1:"请选择车品牌",
            };
        },
        watch:{
        // 对数据进行深度监听 用于设置使用组件的顺序 (多次使用组件并且需要考虑顺序的情况下使用)
            'data.id_card':{
                handler(newName, oldName) {
                      // console.log('data.id_card', chnsg.length,oldName);            
                      ( oldName.length >= 2) ? (this.Drivinglicense = true) : (this.Drivinglicense = false)
                     console.log(this.Drivinglicense);
                    },
                    immediate: true,
                    deep: true,
            }
        },
        methods:{
            successImages(e){
                if(e){
                    uni.showModal({
                        content : '图片上传成功'
                    })
                }
            },
            successImage(e){
                console.log(JSON.parse(e.data).data)
                this.Drivinglicense ?this.data.driving_card.push(JSON.parse(e.data).data[0]) : this.data.id_card.push(JSON.parse(e.data).data[0])
                console.log(this.data.id_card,this.data.driving_card);
            },
            successvideo(e){
                console.log(e)
            },
        }
    }
</script>

使用效果:
这是图片预览效果:

对图片上传数量的限制

图片上传成功提示

取消选择选择图片提示

对于图片上传顺序的限制

没有选择图片的提示

选择图片后效果

到此这篇关于uniapp做小程序的图片(视频)上传的组件封装的文章就介绍到这了,更多相关uniapp小程序上传的组件封装内容请搜索插件窝以前的文章或继续浏览下面的相关文章希望大家以后多多支持插件窝!