uniapp写h5如何封装一个图片上传预览并且有进度条的组件

2023-11-20

开发背景:

首先项目是用uniapp写的h5项目,要求能上传、预览、和进度条展示,还要求总览的时候用缩略图,点开预览要原图,(不得不吐槽一下)
开发环境:
uniapp +阿里云存储

先看截图效果:
在这里插入图片描述
好了直接上代码

// photo-picker.vue
<template> 
    <view class="imgs">
        <view class="image" v-for="(item, index) in localPhotos" :key="index">
            <image class="img" :src="item.path" mode="aspectFill" @click="previewImage(index)"></image> 
            <view class="del" mode="widthFix" @click="delImg(index)">
                <uni-icons color='white' custom-prefix="custom-icon" type="closeempty" size="16"></uni-icons>
            </view>
            
            <view class="file-picker__progress" v-if="(item.progress && item.progress !== 100) || item.progress === 0"> 
                <progress class="file-picker__progress-item" :activeColor="'#FF7300'" :percent="item.progress === -1?0:item.progress" stroke-width="12" :backgroundColor="item.errMsg?'#ff5a5f':'#EBEBEB'"/>
            </view>
        </view>
        <!-- 实例用的插槽 -->
        <slot name="instance" v-if="localPhotos.length===0"></slot>
        <view class="icon_box"  @click="uploadImg()" v-show="isShow && photos.length < astrict">
            <image class="icon-add" src="/static/images/img_photo_1.png"></image>
            <view class="icon-title">上传图片</view> 
        </view>
    </view> 
</template>

<script>
import api from '@/static/api.js';
import { recursionCompressH5 } from '@/static/util.js';
export default {
    props:{
        //原图
        photos:{
            type: [Array,String],
            default: () => [],
            // required: true // 必填 
        },
        //缩略图
        thumbnailPhotos:{
            type: [Array],
            default: () => [],
            required: true // 必填 
        },
        //限制传多少张
        astrict:{
            type: Number,
            default: 1
        }
    },
    data() {
        return {
            localPhotos: [],//保存本地图片
            isShow:true
        }
    },
    methods: {
        //预览图片
        previewImage(current = 0) {
            uni.previewImage({
                current,
                urls: this.photos,
                loop: true,
				indicator: "default",
                longPressActions: {
                    itemList: ['发送给朋友', '保存图片', '收藏'],
                    success: function (data) {
                    },
                    fail: function (err) {
                    }
                }
            })
        },
        //执行回调
        callback(file,i){
            uni.uploadFile({
                url: api.upLoadImg,
                filePath: file.path,
                name: 'file_img',
                success: (uploadFileRes) => {
                    let data = JSON.parse(uploadFileRes.data);

                    this.photos[i]=data.data.url;//图片链接放到原图数组里

                    this.thumbnailPhotos[i] = { path:data.data.thumbnail, progress: 100 }
                    // this.$emit("onSaveThumbnail",this.thumbnailPhotos)//图片链接放到缩略图数组里

                    this.localPhotos[i].progress = 100 
                    this.localPhotos[i].errMsg = false
                    this.$set(this.localPhotos,i,this.localPhotos[i])//本地图片放到存放本地图片的数组里
                    
                    if (++this.num === this.len) {
                        this.isShow = true
                        uni.hideLoading()
                        this.num = 0
                        this.len = 0
                    }
                },
                fail:(err) => {
                    this.localPhotos[i].errMsg = true
                    this.localPhotos[i].progress = -1
                    this.$set(this.localPhotos,i,this.localPhotos[i])//本地图片放到存放本地图片的数组里
                    if (++this.num === this.len) {
                        this.isShow = true
                        uni.hideLoading()
                        this.num = 0
                        this.len = 0
                    }
                }
            })
        },
        //进度条自动前进
        autoStep(v,i){
            let timer  = null
            timer = setInterval(() => { 
                if (v.progress >= 90) {
                    clearInterval(timer);
                }else if(v.progress === -1){
                    clearInterval(timer);
                }else{
                    v.progress += 5
                    this.$set(this.localPhotos,i,v) 
                }
            }, 500);
        },
        //获取图片
        uploadImg() {
            let sun = this.astrict - this.photos.length;
            uni.chooseImage({
                count: sun,
                sizeType: ['compressed'],
                success: (res) => {
                    this.isShow = false
                    uni.showLoading({
                        title: '上传中...',
                        mask:true
                    })
                    this.len =res.tempFilePaths.length
                    this.num = 0
                    res.tempFiles.forEach((v, i) => {
                        v.progress = 0
                        this.localPhotos.push(v)
                    })

                    //走模拟进度条
                    this.localPhotos.forEach((item,index)=>{ 
                        if (item.progress === 0) {
                            //调用模拟进度条
                            this.autoStep(item, index)
                             //调用压缩方法 
                            recursionCompressH5(item,index,this.callback,2) 
                        }
                    })
                },
                fail: (err) => {
                }
            });
        },
        //删除图片
        delImg(index) {
            this.photos.splice(index, 1)
            this.localPhotos.splice(index, 1)
            this.thumbnailPhotos.splice(index, 1)
        },
    },
    watch: {
        thumbnailPhotos() {
            this.localPhotos = JSON.parse(JSON.stringify(this.thumbnailPhotos))
        }
    }, 
}
</script>

<style lang="scss" scoped>
.imgs{
    margin-top:10upx;
    width: 100%;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    
    .image{
        width: 202upx;
        height: 202upx;
        border-radius: 16upx;
        overflow: hidden;
        margin: 0 10upx 10upx 0;
        position: relative;
        
        .img{
            width: 100%;
            height: 100%;
            display: block;
        }
        
        .del{
            background-color: #000;
            opacity: 0.5;
            width: 44upx;
            height: 44upx;
            border-radius: 50%;
            position: absolute;
            top: 4upx;
            right: 4upx;
            text-align: center; 
        }
        .file-picker__progress {
            position: absolute;
            bottom: 0;
            left: 0;
            right: 0;
            /* border: 1px red solid; */
            z-index: 99;
        }
    
        .file-picker__progress-item {
            width: 100%; 
        }
    }
    .icon_box{ 
        width: 202upx;
        height: 202upx; 
        border-radius: 16upx;
        background-color:#F4F4F4;
        text-align: center;
        // margin-top: -10upx;
        .icon-add {
            width: 80upx;
            height: 80upx;  
            margin: 40upx 0 5upx;
        }

        .icon-title { 
            font-size: 24upx;
            font-family: 10pxPingFangSC-Regular, PingFang SC;
            font-weight: 400;
            color: #999999;
        }
    }
}
</style>

如何使用呢?

<upload-file class="img_picker" :astrict="9" :photos.sync="formInfo.medical_treatment_photos" :thumbnailPhotos.sync="formInfo.thumbnail_medical_treatment_photos"/>
//photo是原图的数组   如:["http://draftimg.zhongaihuzhu.com/uploads/20220914/6VaNfQGheXlgsWyyoSLWhxWZoUp6Je4jpS5IS0og.jpg","http://draftimg.zhongaihuzhu.com/uploads/20220914/6VaNfQGheXlgsWyyoSLWhxWZoUp6Je4jpS5IS0og.jpg"]
//thumbnailPhotos是缩略图的数组  
//astrict是上传图片张数,不传默认一张
//此处使用.sync传参可实现子组件修改父组件的数据,

thumbnailPhotos 缩略图的数组,要特别提醒一下,由于要有进度条效果,所以,该数组格式为

[
    {
    path:"http://draftimg.zhongaihuzhu.com/uploads/20220914/6VaNfQGheXlgsWyyoSLWhxWZoUp6Je4jpS5IS0og.jpg",
    progress:0
    }
   ]
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

uniapp写h5如何封装一个图片上传预览并且有进度条的组件 的相关文章

随机推荐

  • form表单中使用fileUpLoad上传文件

    在最近的项目中 需要对用户的头像就行上传 这里了解到使用appche的 大家可自行到mvn库搜索jar包名进行下载 这里需要注意的是代码中对参数的读取 正常情况下我么使用getparameter方法进行读取表单数据 但是因为在form中我们
  • 【Neo4j】第 3 章:使用 Pure Cypher 为您的业务赋能

    大家好 我是Sonhhxg 柒 希望你看完之后 能对你有所帮助 不足请指正 共同学习交流 个人主页 Sonhhxg 柒的博客 CSDN博客 欢迎各位 点赞 收藏 留言 系列专栏 机器学习 ML 自然语言处理 NLP 深度学习 DL fore
  • A Gentle Introduction to Graph Neural Networks(一篇GNN的博客)

    图神经网络 读A Gentle Introduction to Graph Neural Networks笔记 1 直观上的理解 layer后面的标号代表是第几层 要注意每一层都是由比它更深的层相互影响的 比如layer2他可能只有laye
  • 关于专栏基于WordPress的手把手建站教程

    如何建立一个自己的个人博客 建站需要什么基础知识 建站的过程是什么 其实建站真的很容易 WordPress已经很成熟了 基本不需要什么基础知识 如何建站这也是我写的比较用心的一个教程 因此准备写一个手把手教你建站系列教程 本教程基于系统Ub
  • mac 和华为手机互传文件

    参考博客 华为手机传输文件到Mac电脑上 简书 应用场景 1 把资料从手机上的数据备份到电脑上或反向操作 2 需要把资料传给朋友的时候 有两种方式 第一种是通过数据线 传输速度快 但是需要安装软件和使用数据线 具体流程如下 1 先准备一个双
  • 异常检测主要方法总结

    最近对预测及异常检测进行了一些研究和学习 把所学东西做一个汇总整理 欢迎交流拍砖 侵权删 目录 一 时间序列概念 二 时间序列异常检测 三 时序类型 四 异常类型 4 1 点异常 4 2 上下文异常 4 3 集合异常 五 重要概念 5 1
  • 人脸识别趟坑历程

    1 人脸识别概述 人脸识别 是基于人的脸部特征信息进行身份识别的一种生物识别技术 用摄像机或摄像头采集含有人脸的图像或视频流 并自动在图像中检测和跟踪人脸 进而对检测到的人脸进行脸部的一系列相关技术 其中技术包括图像采集 特征定位 身份的确
  • jmeter3.3调用数据库写存储过程注意点

    1 数据库配置页面 2 创建存储过程要保证库里没有同名 本来这句drop语句放在创建存储过程里面的 发现会导致不会执行存储过程 一定要分开写 query type选择 update statement 3 创建存储过程 variable n
  • 5-6)视图与索引

    文章目录 视图 一 视图概述 1 视图的定义 2 视图的分类 3 视图的优缺 二 创建视图 使用T SQL 语句创建视图 创建视图注意的问题 三 使用视图 视图 视图是一种虚拟的数据表 Virtual table 来源于数据表和其他数据 一
  • 实验一:交换机的配置与管理-计算机网络

    交换机的配置与管理 技术原理 交换机的管理方式基本分为两种 带内管理和带外管理 通过交换机的Console端口管理交换机属于带外管理 这种管理方式不占用交换机的网络端口 第一次配置交换机必须利用Console端口进行配置 交换机的命令行操作
  • Python爬虫学习之数据提取(XPath)

    Python爬虫学习之数据提取XPath 概述 常用规则 运算符及介绍 准备工作 实例 文本获取 属性获取 属性值匹配 属性多值匹配 多属性匹配 按序选择 概述 XPath的全称是XML Path Language 即XML路径语言 用来在
  • url参数加密_百度逆推link?url=xxx加密算法“反推技术秒收"

    熟悉百度的站长都知道 凡是被百度搜索引擎收录的网站链接 都会生成一个以baidu开头的多参数跳转链接 而所谓 百度反推技术 的原理就是把百度生成的这个链接地址换成自己想要被收录的页面链接就可以了 然后再进行百度快照的投诉 就可以达到秒来蜘蛛
  • SQL:exec sp_executesql 用法

    這種是無效的過程 declare sql nvarchar 500 where nvarchar 500 i nvarchar 64 p nvarchar 50 id int set id 5 set sql select p AreaCo
  • 机器学习系列(8):人脸识别基本原理及Python实现

    众所周知 人脸识别和人脸验证已经得到大量应用 那么它们之间有什么异同呢 又是如何实现的呢 这里是机器学习系列第八篇 带你揭开它们神秘的面纱 若图片挂了 可移步 https mp weixin qq com s biz MzU4NTY1NDM
  • STC仿真失败

    原因就是购买的下载工具不适合在烧写STC8H3K64S仿真固件后再将该下载工具作为USB转串口工具连接PC与目标板 推测是接入仿真时会重启目标板 不打算细究 换一个普通串口就好了
  • VS编译.cu文件源文件无法打开matrix.h和mex.h问题

    配置好cu和VS相关库文件后CUDA程序仍然报错 无法打开matrix h和mex h 解决办法 1 这两个头文件是matlab中的 可能无法直接在VS中调用 可以通过添加外部依赖项的方法将matlab中的头文件的文件路径添加进来 VS中按
  • 机器学习:聚类算法API初步使用

    学习目标 知道聚类算法API的使用 1 api介绍 sklearn cluster KMeans n clusters 8 参数 n clusters 开始的聚类中心数量 整型 缺省值 8 生成的聚类数 即产生的质心 centroids 数
  • SQL批量处理+JDBC操作大数据及工具类的封装

    SQL批量处理 JDBC操作大数据及工具类的封装 一 批处理 批量处理sql语句 在jdbc的url中添加rewriteBatchedStatements true参数 可以提高批处理执行效率 在我们进行大批量数据操作的时候 需要采用批处理
  • 不使用80,443,端口,域名还需要备案吗?域名没有备案应该怎么选服务器。

    在互联网日益发达的今天 越来越多的个人 企业 公司涌入其中 在服务器 域名 大量供需的情况下身为一个小白应该要注意什么呢 首先要明确你所需要的服务器是国内大陆服务器 如 杭州 扬州 镇江 宁波等 还是海外服务器 如 香港 美国 日本 韩国等
  • uniapp写h5如何封装一个图片上传预览并且有进度条的组件

    开发背景 首先项目是用uniapp写的h5项目 要求能上传 预览 和进度条展示 还要求总览的时候用缩略图 点开预览要原图 不得不吐槽一下 开发环境 uniapp 阿里云存储 先看截图效果 好了直接上代码 photo picker vue