van-uploader上传图片实现过程、使用原生input实现上传图片

news2024/11/20 14:26:03

1、使用van-uploader 

   使用van-uploader组件上传图片,并将其封装成组件,接收传入的参数imglist。图片地址为服务器返回的。

完整代码

<template>
  <div class="image-uploader">
    <div class="list-img" v-for="(src, srcKey) in list" :key="srcKey">
      <van-image
        :src="src"
        width="2.133rem"
        height="2.133rem"
        @click="previewImage(src, srcKey)"
      >
        <template v-slot:loading>
          <van-loading type="spinner" size="20" />
        </template>
        <van-icon
          name="cross"
          size="6"
          class="del-icon"
          color="#fff"
          @click="onDelImage(srcKey)"
        />
      </van-image>
    </div>
    <div class="loading" v-if="isShowLoading">
      <div class="loading-icon">
      </div>
      <div class="loading-text">正在上传</div>
    </div>

    <van-uploader
      class="list-upload"
      :after-read="afterRead"
      accept="image/*"
      :preview-image="false"
      multiple
    />

  </div>
</template>
<script>
import Compressor from 'compressorjs';
import { ImagePreview, Toast } from 'vant';
import { mapGetters } from "vuex";
import { multipleFiles } from '@/api/work';
export default {
  props: {
    imglist: Array,
  },
  data() {
    return {
      list: [],
      isShowLoading: false,
    }
  },
  computed: {
    ...mapGetters([
      "HOST"
    ]),
  },
  watch: {
    imglist() {
      this.list = this.imglist
    },
  },
  mounted() {
    this.list = this.imglist;
  },
  methods: {
    beforeRead(file) {
      return new Promise((resolve) => {
        // compressorjs 默认开启 checkOrientation 选项
        // 会将图片修正为正确方向
        new Compressor(file, {
          success: resolve,
          error(err) {
            console.log(err.message);
          },
        });
      });
    },
    afterRead(file) {
      console.log("afterRead", file)
      this.isShowLoading = true;
      // 多文件上传
      //   let _this = this;
      var formData = new FormData();
      if (file.constructor != Array) {
        formData.append("file", file.file);
      } else {
        file.forEach(element => {
          formData.append("file", element.file);
        });
      }
      multipleFiles(formData).then((res) => {
        if (res.data.code == 20000) {
          file.status = 'done';
          file.message = '';
          let list = res.data.data;
          list.forEach(element => {
            let url = this.HOST + element.afterName;
            this.list.push(url);
          });
          console.log("上传后", this.list)
        }
      }).finally(() => {
        this.isShowLoading = false;
      });
    },

    previewImage(url, urlKey) {
      ImagePreview({
        // 真实数据
        images: this.list,
        showIndex: true,
        loop: true,
        startPosition: urlKey
      });
    },

    //删除图片
    onDelImage(index) {
      this.list.splice(index, 1);
    },
  }
}
</script>
<style lang="scss" scoped>
.image-uploader {
  width: 100%;
  border: 1px dashed rgb(220 223 230);
  display: flex;
  flex-wrap: wrap;
  .list-img {
    position: relative;
    margin: 5px;
  }
  .del-icon {
    position: absolute;
    top: 0;
    right: 0;
    width: 16px;
    height: 16px;
    text-align: right;
    background-color: rgb(0 0 0 / 70%);
    border-radius: 0 0 0 12px;
  }
  .list-upload {
    margin: 5px;
  }
}
.loading {
  margin: 5px;
  width: 80px;
  height: 80px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #c6c7c9;
  background: rgb(247 248 250);
  margin-right: 5px;
  animation-duration: 2s;
  .loading-text {
    margin-top: 6px;
  }
}
.loading-icon {
  width: 50px;
  height: 50px;
  margin: 0 auto;
  background-color: #f7f8fa;
}
</style>

 主要代码

1、添加正在上传的提示

在图片上传和image显示上传的图片间会存在等待时间,因此加了一个下图所示的正在上传,在调用上传的方法是显示样式,图片接收成功后隐藏样式。(本来还想加一个loading加载的动态效果,奈何太菜没有搞出来)

<div class="loading" v-if="isShowLoading">
   <div class="loading-icon">
   </div>
   <div class="loading-text">正在上传</div>
</div>

2、实现多文件上传(multiple)

官方文档:Vant 2 - Mobile UI Components built on Vue

afterRead(file) {
      console.log("afterRead", file)
      this.isShowLoading = true;
      let _this = this;
      var formData = new FormData();
      if (file.constructor != Array) {
        formData.append("file", file.file);
      } else {
        file.forEach(element => {
          formData.append("file", element.file);
        });
      }
      multipleFiles(formData).then((res) => {
        if (res.data.code == 20000) {
          let list = res.data.data;
          list.forEach(element => {
            let url = this.HOST + element.afterName;//根据返回值拼接成需要的图片地址
            _this.list.push(url);
          });
          console.log("上传后", this.list)
        }
      }).finally(() => {
        this.isShowLoading = false;
      });
    },

 开启图片多选功能后,打印一下file值

选择一张图片上传,file值如下图所示,返回值是一个对象

 选择两个图片上传,file值是一个数组

因为上传一个图片和多个图片,file的值类型不同,所以在转FormData前先判断一下file是不是数组,如果是数组就用foreach循环

if (file.constructor != Array) {
  formData.append("file", file.file);
} else {
  file.forEach(element => {
     formData.append("file", element.file);
  });
}

2、使用原生input 

 1、用input代替van-uploader

  <div class="uploader_box list-upload">
      <input
        type="file"
        id="logimg"
        accept="image/*"
        multiple="multiple"
        @change="change($event)"
      />
      <van-icon class="camera-icon" name="photograph" />
  </div> 

2、上传文件的方法

   change(e) {
      if (e.target.files.length > 0) {
        this.getUrl(e.target.files); //多文件上传
      }
    },
    getUrl(file) {
      console.log("getUrl", file)
      this.isShowLoading = true;

      // 多文件上传
      let _this = this;
      var formData = new FormData();
      // file.forEach无效,使用for( ; ; ;)循环
      for (let i = 0; i < file.length; i++) {
        formData.append("file", file[i]);
      }
      let config = {
        headers: {
          "Content-Type": "multipart/form-data"
        }
      };
      multipleFiles(formData, config).then((res) => {
        if (res.data.code == 20000) {
          file.status = 'done';
          file.message = '';
          let list = res.data.data;
          list.forEach(element => {
            let url = this.HOST + element.afterName;
            _this.list.push(url);
          });
        }
      }).catch(error => {
        Toast.fail("上传文件接口调用失败")
      }).finally(() => {
        this.isShowLoading = false;
      });
    },

 上传一个文件时,file的返回值

 上传两个文件值,file的返回值

  返回值都是一个object对象,就直接使用foreach将文件转成FormData。

3、实现一个跟van-uploader相同的样式

.uploader_box {
  width: 80px;
  height: 80px;
  overflow: hidden;
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  box-sizing: border-box;
  margin: 0 8px 8px 0;
  // border: 1px dashed rgb(220 223 230);
  background-color: rgb(247 248 250);
  #logimg {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    cursor: pointer;
  }
  .camera-icon {
    color: rgb(220 222 224);
    font-size: 24px;
  }
}

样式实现效果:

 3、在文件中引入组件

<div style="padding: 5px 10px 0 10px">
   <p style="color: #646566">答案补充:</p>
   <uploader :imglist="data.topic.topicResult.imgSrc" />
</div>

提示:如果出现部分图片能上传,部分图片不能上传,可以看看是不是服务器上设置了图片的大小。

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

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

相关文章

html 导入百度地图 网页中如何导入百度地图

先看案例如图所示 首先我们需要知道我们想要标注地点的经纬度 经纬度查询网址如下 图中以同程大厦为例 经纬度查询定位 拾取坐标系统 经纬度查询地图 好了 准备工作做好 现在开始编码~ 第一步 html css部分 注意点1. #map 命名 不要随意更改 如影响到您的布局 您可以在外面在…

多种方法解决前后端报出的SyntaxError: xxx is not valid JSON的问题,比如“[object Object]“ is not valid JSON

文章目录1. 复现问题2. 分析问题3. 解决问题4. 该错误的其他解决方法5. 文章总结1. 复现问题 今天启动后端服务&#xff0c;访问knife4j文档时&#xff0c;却报出如下错误&#xff1a; 于是&#xff0c;按F12打开调试页面板&#xff0c;找到了具体的错误信息&#xff0c;如下所…

那些你不得不了解的HTML基础

瞧一瞧&#xff0c;看一看&#xff0c;新鲜的HTML出笼了 目录 一、HTML基本语法&#xff08;标签&#xff09; 注释 标题 段落 换行 特殊转义字符 格式化标签 图片 超链接a标签 表格标签 列表标签 表单标签 无语义标签 二、基于上述实现的两个案例 制作一份简历…

vue 之 CSS进行样式穿透的方法(/deep/、::v-deep、>>> 、:deep、额外的全局<style>)

一、简介 在很多vue的组件库 , 如vant&#xff0c;elementUI&#xff0c; iview等都可能自定义一些样式文件&#xff0c;如果我们在项目中引入了样式组件或者通过v-html渲染了数据&#xff0c;然后想要去修改他们内部的某元素的样式, 直接修改样式很可能不起作用&#xff0c;修…

做一个前端网页送给女朋友~轮播图+纪念日

文章目录1. 轮播图框架2. 轮播图大盒子实现1. 盒子及图片的可视化2. 将图片重叠起来并放入轮播图盒子中...相对定位与绝对定位3. 添加左右按钮4. 点击按钮跳转图片5. 鼠标离开图片轮播图按钮隐藏6. 添加小圆点按钮7. 点击小圆点跳转图片并且该小圆点变色8. 自动轮播9. 最后一步…

Vue项目中ESLint配置(VScode)

Vue项目中ESLint配置&#xff08;VScode&#xff09; 1.VScode的配置格式化代码 1.1下载eslint插件 1.2配置setting.json 打开左上角文件-首选项-设置,在设置中搜索eslint&#xff0c;点击并翻页到最下面&#xff0c;点击setting.json进行配置&#xff1a; // 值设置为true时…

Springboot Long类型数据太长返回给前端,精度丢失问题 复现、解决

前言 惯例&#xff0c;收到兄弟求救&#xff0c;关于long类型丢失精度的问题&#xff1a; 存在一个初学者不会&#xff0c;就会有第二个初学者不会&#xff0c;所以我出手。 正文 不多说&#xff0c;开搞。 如题&#xff0c; 后端返回的数据 给到 前端&#xff0c; Long类型数…

【Vue】踩坑日记:Scoped下动画无效,曾经以为百利而无一害的Scoped,也有自己的限制

文章目录问题描述解决过程玩味Vue Scoped知识点解决方法问题描述 ​ 在开发的前期&#xff0c;我清晰的记得使用动画完成了图片放大的效果&#xff0c;当时还写了一篇博文 http://t.csdn.cn/lA9aq上了热榜。可是过了几天之后&#xff0c;这个效果居然“失效了”&#xff0c;我…

若依前后端分离新窗口打开页面,如何使用this.$router.resolve解决

若依前后端分离新窗口打开页面this.$router.resolve 欢迎遇到同样问题的同学阅读 例如系统后台要求点击【可视化大屏】菜单&#xff0c;需要打开新窗口显示&#xff0c;但不能影响原窗口显示系统页面&#xff0c;网上查询了一圈都是比较片面的只提到了this.$router.resolve&a…

JS时间戳转换方式

前言 在js中将时间戳转换为常用的时间格式&#xff0c;有三种主要的方式 1、使用JS中已有的函数&#xff0c;例如getFullYear(),getMonth()等&#xff0c;将时间戳直接转换成对应的年月&#xff1b; 2、创建时间过滤器&#xff0c;在其他的页面中直接调用该过滤器&#xff0c;转…

npm install 安装失败常见问题解决办法

安装cnpm npm install -g cnpm --registryhttp://registry.npm.taobao.org安装完之后可以通过cnpm -v 检验是否安装成功。 显示当前的镜像网址 npm get registrycnpm install安装依赖 cnpm install在运行cnpm install 中&#xff0c;你可以会遇到cnpm : 无法加载文件 C:\Us…

微信小程序搜索框实现模糊查询

目录 前言一、概述二、步骤三、效果展示总结前言 主要实现功能&#xff0c;无美化&#xff0c;如需请自设 一、概述 开发工具&#xff1a;微信开发者工具 通过对微信原生组件input绑定事件实现对已获取的列表元素模糊查询的操作 二、步骤 在文件中新建一个goodFilter.wxs文…

THREE.js

电子书网站http://www.webgl3d.cn链接 特定版本three.js下载 github链接&#xff1a;https://github.com/mrdoob/three.js github链接查看所有版本&#xff1a;https://github.com/mrdoob/three.js/releases 选择你需要的版本three.js文件包下载&#xff0c;然后解压即可。…

【node进阶】浅析Koa框架---ejs模板|文件上传|操作mongoDB

✅ 作者简介&#xff1a;一名普通本科大三的学生&#xff0c;致力于提高前端开发能力 ✨ 个人主页&#xff1a;前端小白在前进的主页 &#x1f525; 系列专栏 &#xff1a; node.js学习专栏 ⭐️ 个人社区 : 个人交流社区 &#x1f340; 学习格言: ☀️ 打不倒你的会使你更强&a…

无法将“node.exe”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。

NodeJS配置相关问题 报错原因路径配置 报错 1.无法将“node.exe”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。 2.终端输入node -v&#xff0c;发出提示&#xff1a;nodejs在cmd提示不是内部或外部命令解决方法 3.终端输入npm -v&#xff0c;发出提示&#xff1a;n…

用jQuery实现轮播图——超简单(代码解释)

先看效果 鼠标悬浮时停止轮播&#xff0c;离开时自动轮播&#xff0c;点下一张小圆点会随着动 直接上代码 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><style>.wrapper {width: 600px;height: 350…

uniapp 前端获取微信小程序 URL Link (HTTPS调用)

前端基于 uniapp 获取微信小程序 URL Link 短链&#xff0c;适用于短信、邮件、网页、微信内等拉起小程序的业务场景。目前仅针对国内非个人主体的小程序开放。 前言&#xff1a;微信小程序此前可以在小程序管理后台-工具 中直接快捷生成小程序指定页面的 https 短链&#xff…

chrome插件-Web开发者助手 FeHelper

FeHelper是一个非常好用的插件&#xff0c;支持Chrome、Firefox、MS-Edge浏览器&#xff0c;工具集包括 JSON自动/手动格式化、JSON内容比对、代码美化与压缩、信息编解码转换、二维码生成与解码、图片Base64编解码转换、Markdown、 网页油猴、网页取色器、脑图(Xmind)等贴心工…

使用el-upload组件实现递归多文件上传

一、需求描述&#xff1a;在页面上点击按钮弹出选择电脑文件的界面&#xff0c;可以一次性选择多个文件一起上传到服务器上&#xff0c;并把上传成功的文件展示在页面上。 二、问题阐述&#xff1a;el-upload是支持多文件上传的&#xff0c;但是是同步进行的&#xff0c;你点击…

Three.js学习五——让模型沿着轨迹移动

目录流程搭建场景环境添加模型增加运动轨迹让模型沿轨迹运动完整代码和效果流程 基本流程 1、添加模型 2、增加运动轨迹 3、让模型沿轨迹运动 工程文件结构如下图&#xff1a; static&#xff1a;存放静态资源文件 three.js-master&#xff1a;为官网下载的代码包&#xff0c;…