input file结合vue3和vant实现上传图片效果,并显示上传进度百分比%

news2024/11/22 1:43:25

这里写自定义目录标题

  • 采用的dom结构是input file,label事件绑定,一下为代码
    • 传入参数为uploadNum
    • 实现效果如图
      • 上传中,图片1
      • 上传成功,图片2

采用的dom结构是input file,label事件绑定,一下为代码

传入参数为uploadNum

<template>
  <div class="my-img-upload">
    <van-space wrap>
      <!-- 图片列表 -->
      <div
        class="uploader-upload uploader-upload-list"
        v-for="(imgItem, index) in imgArr"
        :key="index"
      >
        <label class="uploader-icon-wrap">
          <van-icon name="photograph" color="#dcdee0" />
        </label>
        <div v-if="imgItem.status != 'success'" class="loading-wrap">
          <van-loading color="#ffffff" size="22" />
          <div class="text">上传中{{ imgItem.progress }}%</div>
        </div>
        <div class="img-wrap" v-else @click="preImg(index)">
          <img :src="imgItem.url" alt="" style="width: 100%" />
          <div class="del-icon" @click.stop="delImg(index)">
            <van-icon name="cross" size="12px" color="#ffffff" />
          </div>
        </div>
      </div>
      <!-- 上传的操作 -->
      <div class="uploader-upload">
        <label class="uploader-icon-wrap" for="uploader-ipt">
          <van-icon name="photograph" color="#dcdee0" />
        </label>
        <input
          type="file"
          id="uploader-ipt"
          class="uploader-input"
          accept="image/*"
          @change="changeFileInfo"
        />
      </div>
    </van-space>
  </div>
</template>

<script setup>
import axios from "axios";
import xToast from "@/util/toast.js";
import { showImagePreview } from "vant";
import { ref } from "vue";

const props = defineProps({
  uploadNum: {
    // 上传图片的数量
    type: Number,
    default() {
      return 10;
    },
  },
});

const imgArr = ref([]);

// 预览图片
function preImg(index) {
  const imgUrlList = imgArr.value.map((item) => item.url);
  showImagePreview({
    images: imgUrlList,
    startPosition: index,
  });
}

// 删除图片
function delImg(index) {
  imgArr.value.splice(index, 1);
}

function changeFileInfo(e) {
  if (imgArr.value.length >= props.uploadNum) {
    xToast.show({
      type: "error",
      content: `最多上传${props.uploadNum}张图片`,
    });
    return false;
  }
  const files = e.target.files;
  const oFile = files[0];

  if (!isImageFile(files[0].name)) {
    xToast.show({
      type: "error",
      content: "请选择图片文件",
      time: 3000,
    });
    return false;
  }
  let objImage = {
    url: URL.createObjectURL(oFile),
    name: oFile.name,
    status: "uploading",
    statusbar: "上传中...",
    progress: 0,
  };
  imgArr.value.push(objImage);
  upLoadRequest(oFile);
}

function upLoadRequest(file) {
  const dataFile = new FormData();
  dataFile.append("file", file);
  return new Promise((resolve, reject) => {
    axios({
      method: "post",
      url: "/api/upload", // 大概率需要代理
      headers: {
        "Content-Type": "multipart/form-data",
      },
      data: dataFile,
      onUploadProgress: function (progressEvent) {
        const percentCompleted = Math.round(
          (progressEvent.loaded * 100) / progressEvent.total
        );
        imgArr.value[imgArr.value.length - 1].progress = percentCompleted;
      },
    })
      .then((res) => {
        if (res.code == 200) {
          // 注意这里可能需要根据实际响应结构调整
          imgArr.value[imgArr.value.length - 1] = {
            progress: 100,
            url: res.data.fileId,
            status: "success",
            message: "上传成功",
          };
          resolve();
        } else {
          imgArr.value.splice(imgArr.value.length - 1, 1);
          xToast.show({
            type: "error",
            content: "上传失败",
            time: 3000,
          });
          reject(new Error("上传失败"));
        }
      })
      .catch((error) => {
        imgArr.value.splice(imgArr.value.length - 1, 1);
        console.error("上传过程中发生错误:", error);
        xToast.show({
          type: "error",
          content: "上传过程中发生错误",
          time: 3000,
        });
        reject(error);
      });
  });
}

function isImageFile(filename) {
  // 定义常见的图片格式扩展名
  const imageExtensions = [
    ".jpg",
    ".jpeg",
    ".png",
    ".gif",
    ".bmp",
    ".webp",
    ".svg",
    ".tiff",
    ".ico",
  ];

  const extension = filename.split(".").pop().toLowerCase();
  return imageExtensions.includes(`.${extension}`);
}
</script>
<style lang="less" scoped>
.my-img-upload {
  display: flex;
  margin-bottom: 20px;

  .uploader-upload {
    width: 80px;
    height: 80px;
    background: #fff;
    position: relative;

    .img-wrap {
      position: absolute;
      left: 0;
      top: 0;
      z-index: 100;
      width: 100%;
      height: 100%;
      font-size: 0;
      display: flex;
      align-items: center;
      justify-content: center;
      background-color: #ffffff;
      overflow: hidden;

      img {
        max-width: 100%;
        max-height: 100%;
      }

      .del-icon {
        position: absolute;
        right: 0;
        top: 0;
        z-index: 100;
        background-color: rgba(0, 0, 0, 0.7);
        border-radius: 0 0 0 12px;
        width: 15px;
        height: 15px;
        text-align: right;
      }
    }

    .loading-wrap {
      position: absolute;
      left: 0;
      top: 0;
      z-index: 100;
      width: 100%;
      height: 100%;
      display: flex;
      align-items: center;
      justify-content: center;
      background-color: rgba(50, 50, 51, 0.88);
      flex-direction: column;

      .text {
        font-size: 0.32rem;
        color: #fff;
        margin-top: 4px;
      }
    }

    .uploader-icon-wrap {
      position: absolute;
      z-index: 10;
      left: 0;
      top: 0;
      width: 100%;
      height: 100%;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    .uploader-input {
      width: 100%;
      opacity: 0;
    }
  }
}
</style>

实现效果如图

上传中,图片1

在这里插入图片描述

上传成功,图片2

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2245018.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CSS优化file控件样式

<div class"file-box"><input type"button" class"btn" value"选择文件" /><inputtype"file"class"file"id"upimg"change"previewFiles"multiple/></div><!-- Vu…

AJAX笔记 (速通精华版)

AJAX&#xff08;Asynchronous Javascript And Xml&#xff09; 此笔记来自于动力节点最美老杜 传统请求及缺点 传统的请求都有哪些&#xff1f; 直接在浏览器地址栏上输入URL。点击超链接提交 form 表单使用 JS 代码发送请求 window.open(url)document.location.href urlwi…

某校园网登录界面前端加密绕过

前言 尝试对学校校园网登录框进行爆破&#xff0c;发现密码在前端被加密了 Burp抓包 抓包信息 DDDDD2022***&upass3d5c84b6fb1dc75987884f39c05b0e6a123456782&R10&R21&para00&0MKKey123456&v6ip From表单提交上来的文本这些参数&#xff0c;DDDD是…

《生成式 AI》课程 第3講 CODE TASK执行文章摘要的机器人

课程 《生成式 AI》课程 第3講&#xff1a;訓練不了人工智慧嗎&#xff1f;你可以訓練你自己-CSDN博客 任务1:总结 1.我们希望你创建一个可以执行文章摘要的机器人。 2.设计一个提示符&#xff0c;使语言模型能够对文章进行总结。 model: gpt-4o-mini,#gpt-3.5-turbo, import…

Github客户端工具github-desktop使用教程

文章目录 1.客户端工具的介绍2.客户端工具使用感受3.仓库的创建4.初步尝试5.本地文件和仓库路径5.1原理说明5.2修改文件5.3版本号的说明5.4结合码云解释5.5版本号的查找 6.分支管理6.1分支的引入6.2分支合并6.3创建测试仓库6.4创建测试分支6.5合并分支6.6合并效果查看6.7分支冲…

python实战案例----使用 PyQt5 构建简单的 HTTP 接口测试工具

python实战案例----使用 PyQt5 构建简单的 HTTP 接口测试工具 文章目录 python实战案例----使用 PyQt5 构建简单的 HTTP 接口测试工具项目背景技术栈用户界面核心功能实现结果展示完整代码总结 在现代软件开发中&#xff0c;测试接口的有效性与响应情况变得尤为重要。本文将指导…

JavaScript的类型转换

类型转换 &#xff1a; 隐式转换和显示转换 一般的&#xff0c;默认单选框和多选框传过来的值都是字符串 JavaScript是弱数据类型&#xff1a;JavaScript不知道变量属于哪种类型&#xff0c;需要赋值了才清楚。 缺点&#xff1a;使用表单、prompt获取过来的数据默认是字符串类…

Spring Boot中使用AOP和反射机制设计一个基于redis的幂等注解,简单易懂教程

由于对于一些非查询操作&#xff0c;有时候需要保证该操作是幂等的&#xff0c;该帖子设计幂等注解的原理是使用AOP和反射机制获取方法的类、方法和参数&#xff0c;然后拼接形成一个幂等键&#xff0c;当下一次有重复操作过来的时候&#xff0c;判断该幂等键是否存放&#xff…

一文详细深入总结服务器选型

1. 题记&#xff1a; 服务器选型工作是项目规划检讨的一项非常重要的工作&#xff0c;本文详细深入总结服务器选型。 2. 服务器基础知识概览 2.1 服务器的定义与功能 2.1 .1 定义 服务器是一种高性能计算机&#xff0c;其设计目的是在网络中提供服务。它可以处理来自多个客…

接口测试用例设计的关键步骤与技巧解析!

简介 接口测试在需求分析完成之后&#xff0c;即可设计对应的接口测试用例&#xff0c;然后根据用例进行接口测试。接口测试用例的设计也需要用到黑盒测试用例设计方法&#xff0c;和测试流程与理论章节的功能测试用例设计的方法类似&#xff0c;设计过程中还需要增加与接口特…

WPF下 DataGrid加入序号列

先上代码&#xff1a; <DataGrid Name"DGV" AutoGenerateColumns"False" Grid.Row"0" Grid.Column"0" HorizontalGridLinesBrush"RoyalBlue" VerticalGridLinesBrush"Tomato" CanUserAddRows"False&qu…

WebSocket详解、WebSocket入门案例

目录 1.1 WebSocket介绍 http协议&#xff1a; webSocket协议&#xff1a; 1.2WebSocket协议&#xff1a; 1.3客户端&#xff08;浏览器&#xff09;实现 1.3.2 WebSocket对象的相关事宜&#xff1a; 1.3.3 WebSOcket方法 1.4 服务端实现 服务端如何接收客户端发送的请…

大模型本地部署实践:Ollama+Open-WebUI(MacOS)

目录 什么是Ollama Ollama安装 对话界面可视化&#xff1f;Open-WebUI&#xff01; 安装Open-WebUI 什么是Ollama Ollama是一个为简化大语言模型本地部署与交互的开源框架。它提供了用户友好的接口&#xff0c;帮助开发者和模型爱好者在没有依赖外部API的基础上高效地运行、…

12万字 | 企业智慧数字化运营平台重构建设项目实施技术方案

本项目旨在推动企业数字化运营平台的重构&#xff0c;以支持组织改革和数字化转型战略的实施&#xff0c;提升企业智慧化运营管理能力。项目将优化订单受理流程&#xff0c;增强业务受理能力&#xff0c;提高客户服务体验和内部管控能力&#xff0c;同时提升营销资源管理的制度…

基于Lora通讯加STM32空气质量检测WIFI通讯-分享

目录 目录 前言 一、本设计主要实现哪些很“开门”功能&#xff1f; 二、电路设计原理图 1.电路图采用Altium Designer进行设计&#xff1a; 2.实物展示图片 三、程序源代码设计 四、获取资料内容 前言 随着环境污染问题的日益严重&#xff0c;空气质量的监测与管理已经…

cesium for unity的使用

先聊聊导入 看到这里的因该能够知道&#xff0c;官网以及网上绝大多数的方法都导入不进来&#xff0c;那么解决方法如下: 两个链接&#xff1a;按照顺序依次下载这两个tgz和zip&#xff0c;其中tgz为主要部分&#xff0c;zip为示例工程项目 如果您要查看示例工程项目的话&am…

数据结构_图的遍历

深度优先搜索遍历 遍历思想 邻接矩阵上的遍历算法 void Map::DFSTraverse() {int i, v;for (i 0; i < MaxLen; i){visited[i] false;}for (i 0; i < Vexnum; i){// 如果顶点未访问&#xff0c;则进行深度优先搜索if (visited[i] false){DFS(i);}}cout << endl…

MySQL时间字段TIMESTAMP和DATETIME

SELECT global.time_zone, session.time_zone;查询数据库的全局时区和当前会话的时区信息&#xff0c;一般如果使用navicat进行连接&#xff0c;没有显示指定时区信息&#xff0c;会默认使用system_time_zone。 可以使用 SET time_zone 08:00; SELECT global.time_zone, sess…

AQS 理解 及不可重入锁实现

由于目前水平有限&#xff0c;只是写出作者目前对 aqs的简单理解&#xff0c;有错误还请评论指证 AQS是什么 Aqs是java.util.concurrent 包下的一个抽象队列 同步器类&#xff0c;被简写为英文AQS&#xff0c; 我认为 可以把他理解 为一个 实现 自定义 锁的 一个具体的框架 …

nginx源码安装配置ssl域名

nginx源码安装 下载 wget http://nginx.org/download/nginx-1.24.0.tar.gz 解压 tar -zxvf nginx-1.24.0.tar.gz 下载openssl apt install openssl 安装nginx cd nginx-1.24.0 sudo apt-get install libpcre3 libpcre3-dev ./configure --prefix=/home/nginx24 --with-http_ss…