自定义vue组件--实现多图片上传

2023-11-15

一 引入

文件上传在日常的开发中是一项基本的操作,在前端中得以广泛的使用,因此将其封装成一个组件显得极为重要,本文主要是基于vue实现的自定义多图片上传组件.

二 自定义vue上传组件

MultiUpload组件的封装

<template>
  <div>
    <el-upload :disabled="uploadEdit" class="uploader" :headers="authorToken" :action="UPLOAD_URL" :auto-upload="true"
               :file-list="fileList" list-type="picture-card" :limit="limit?limit:9" :accept="fileType?fileType:'image/*'"
               :on-success="handleGoodsImagesUploadSuccess" :before-upload="handlebeforeUpload" :multiple="true"
               ref="fileupload" :on-exceed="handleUploadExceed" :on-remove="handleRemove"
               :on-preview="handlePictureCardPreview">
      <i class="el-icon-plus"></i>
    </el-upload>
    <el-dialog :disabled="uploadEdit" :append-to-body="true" :visible.sync="dialogImgVisible" style="z-index: 3000;text-align: center;"
               :close-on-click-modal="false" :close-on-press-escape="false" custom-class="pub_dialog">
      <img width="80%" :src="dialogImageUrl" alt="" />
    </el-dialog>
  </div>
</template>
<!--
	使用用例
	uploadEdit 是否启用编辑 true false
	fileType可以是
	audio/*表示“任何音频文件
	video/*表示“任何视频文件
	image/*表示“任何图像文件
	还可以以逗号拼接,如image/*,.pdf
	<multi-upload v-model="form.voucherUrlList" :fileType="image/*"></multi-upload>
	import MultiUpload from '@/components/Upload/MultiUpload'
	components: {
		MultiUpload
	},
-->


<script>
export default {
  props: {
    value: {
      type: Array,
      default: () => []
    },
    limit: {
      type: Number,
      default: 9
    },
    fileType: String,
    uploadEdit: Boolean,
  },
  data() {
    return {
      authorToken: {
        'Authorization': 'Bearer ' + JSON.parse(window.sessionStorage.getItem('cncloud-access_token')).content
      },
      UPLOAD_URL: "/admin/sys-file/upload", // 上传的图片服务器地址 即上传图片后台接口的路径
      loading: '',
      param: {
        token: ''
      },
      dialogImageUrl: "",
      dialogImgVisible: false,
      disabled: false,
      imgs:[],
      num:0,
      fileNum:0
    }
  },
  computed: {
    // ['xxx', 'xxx'] 转换为 [{url: 'xxx'}, {url: 'xxx'}]
    fileList() {
      return this.value.map(url => ({
        url
      }))
    }
  },
  methods: {
    handlePictureCardPreview: function(file) {
      this.dialogImageUrl = file.url;
      this.dialogImgVisible = true;
    },
    handleRemove: function(file, fileList) {
      // fileList 为删除后的文件列表
      const value = fileList.map(v => v.url)
      this.$emit('input', value)
    },
    handleGoodsImagesUploadSuccess(response, file, fileList) {
      debugger
      console.log(response);
      console.log(fileList);

      if (response.code == 0) {
        debugger;
        let imageUrl = response.data.url;
        this.imgs.push(imageUrl);
        this.num++;
        if(this.num == this.fileNum){
          this.num = 0;
          this.fileNum = 0;
          // 这里如果 this.value.push(imageUrl) 这么写,vue会报出警告,大概意思是value作为props不应该在子组件中被修改
          // 应该根据 value 得到新的值,而不能修改它,this.value.concat(imageUrl)也是可以的,concat方法返回新的数组
          // this.$emit('input', [...this.value, imageUrl])
          this.$emit('input', this.value.concat(this.imgs))
          this.imgs =[];
        }
      } else {
        this.$message.error(file.name + '上传失败!');
      }
    },
    handlebeforeUpload(file) {
      // 这里做可以做文件校验操作
      const isImg = /^image\/\w+$/i.test(file.type)
      if (!isImg && this.fileType == 'image/*') {
        this.$message.error('只能上传 JPG、PNG、GIF 格式!')
        return false
      }
      this.fileNum++;
      console.log(this.fileNum);
    },
    handleUploadExceed() {
      this.$message.error(`最多上传${this.limit}张图片`)
    },
  }
}
</script>
<style>
/*去除upload组件过渡效果*/
.el-upload-list__item {
  transition: none !important;
}
</style>
<style scoped lang="scss">


.hide>>>.el-upload--picture-card {
  display: none;
}
</style>

业务端的使用
在这里插入图片描述
在这里插入图片描述

三 后端代码实现

根据自己的后端代码具体实现,这里不做过多阐述

@RestController
@AllArgsConstructor
@RequestMapping("/sys-file")
@Api(value = "sys-file", tags = "文件管理")
public class SysFileController {

    private final SysFileService sysFileService;
    /**
     * 上传文件 文件名采用uuid,避免原始文件名中带"-"符号导致下载的时候解析出现异常
     *
     * @param file 资源
     * @return R(/ admin / bucketName / filename)
     */
    @PostMapping(value = "/upload")
    @Inner(value = false)
    public R upload(@RequestPart("file") MultipartFile file) {
        return sysFileService.uploadFile(file);
    }

    /**
     * 获取文件
     *
     * @param bucket   桶名称
     * @param fileName 文件空间/名称
     * @param response
     * @return
     */
    @Inner(false)
    @GetMapping("/{bucket}/{fileName}")
    public void file(@PathVariable String bucket, @PathVariable String fileName, HttpServletResponse response) {
        sysFileService.getFile(bucket, fileName, response);
    }
}

注意事项:

  • 后端接受图片的参数类型为String数组
  • 将组件中token和upload修改为自己项目本身的路径

四 基于mybatis的BaseTypeHandler实现自定义数据类型间的转换

mybatis为我们提供了个BaseTypeHandler的抽象类,可以帮助我们实现java类型和数据库之间相互类型的转换,我们知道String数组并并没有相对应的数据库字段类型,我们可以把他转换成以逗号相隔的字符串保存在数据库中,在java实体类映射转换时,又将其转换成相应的String数组

具体实现逻辑如下:

/**
 * Mybatis数组,符串互转
 * <p>
 * MappedJdbcTypes 数据库中的数据类型 MappedTypes java中的的数据类型
 *
 * @author likun
 * @date 2021-11-20
 */
@MappedTypes(value = { String[].class }) //java实体类数据类型
@MappedJdbcTypes(value = JdbcType.VARCHAR) // 数据库里面对应字段的类型
public class JsonStringArrayTypeHandler extends BaseTypeHandler<String[]> {

	@Override
	public void setNonNullParameter(PreparedStatement ps, int i, String[] parameter, JdbcType jdbcType)
			throws SQLException {
		ps.setString(i, ArrayUtil.join(parameter, StrUtil.COMMA));
	}

	@Override
	@SneakyThrows
	public String[] getNullableResult(ResultSet rs, String columnName) {
		String reString = rs.getString(columnName);
		return Convert.toStrArray(reString);
	}

	@Override
	@SneakyThrows
	public String[] getNullableResult(ResultSet rs, int columnIndex) {
		String reString = rs.getString(columnIndex);
		return Convert.toStrArray(reString);
	}

	@Override
	@SneakyThrows
	public String[] getNullableResult(CallableStatement cs, int columnIndex) {
		String reString = cs.getString(columnIndex);
		return Convert.toStrArray(reString);
	}

}

查看转换结果
在这里插入图片描述
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

自定义vue组件--实现多图片上传 的相关文章

随机推荐

  • Linux实现使用定时任务执行php程序(以及定时任务url带参数)

    php程序已经写好了 位置 data html XXX redis to mysql php php安装位置为 app bin php 查找php安装位置使用 whereis php which php php v which 这条命令主要
  • 1.C#/.NET开发环境安装(Windows)

    文章目录 一 VS2022 1 下载 VS 2022 Community 2 安装 3 第一个VS项目Hello World 4 补充 二 VS2019 1 下载VS 2019 Community 2 安装 三 游戏开发引擎Unity 四
  • centos 安装mysql 5.7

    centos安装mysql 1 检查系统中是否已安装 MySQL 如果已安装 请参考此文章卸载 rpm qa grep mysql 在新版本的CentOS7中 默认的数据库已更新为了Mariadb 而非 MySQL 所以执行 yum ins
  • 转:车规芯片的AEC-Q100测试标准

    距离上一次发文章已经过去了10个月了 这10个月里 不想错过跟小孩待在一起的每一个时刻 额呸 就是因为懒 一直没有更新文章 特此最近开始逼迫自己不断的学习 重新开始进行公众号的更新 最近这小半年一直在弄跟芯片相关的一些工作 并且由于缺芯的原
  • 【华为OD机试】水仙花数Ⅰ【2023 B卷

    华为OD机试 真题 点这里 华为OD机试 真题考点分类 点这里 题目描述 所谓水仙花数 是指一个n位的正整数 其各位数字的n次方和等于该数本身 例如153是水仙花数 153是一个3位数 并且153 1 3 5 3 3 3 输入描述 第一行输
  • ScrumAlliance对Agile Coach的能力定义了五个部分

    1 Assess Discovery Diretion 评估 发现 指导 评估团队 发现问题 提出指导意见 2 Balance Coaching Consulting 平衡教练和咨询的工作 提供咨询方案 也提供教练的工作 3 Catalyz
  • 2022全国职业技能大赛-网络安全赛题解析总结①(超详细)

    2022全国职业技能大赛 网络安全赛题解析总结 自己得思路 模块A 基础设施设置与安全加固 20分 模块B 网络安全事件响应 数字取证调查和应用安全 40分 模块C CTF夺旗 攻击 20分 模块D CTF夺旗 防御 20分 有什么不懂得可
  • (libevent) 基础demo

    文章目录 介绍 Code 并发服务器 signal fifo END P S 简单客户端代码 介绍 官网 libevent linux中下载 apt get install libevent dev 官网的简介 The libevent A
  • JAVA多线程-锁机制

    一 synchronized 在多线程并发编程中 synchronized 一直是元老级角色 很多人都会称呼它为重量级锁 但是 随着 Java SE 1 6 对synchronized 进行了各种优化之后 有些情况下它就并不那么重 sync
  • 深度学习------用NN、CNN、RNN神经网络实现mnist数据集处理

    1 用NN神经网络完成MNIST数据集处理 用NN神经网络完成MNIST数据集处理 1 导包 import tensorflow as tf import numpy as np import matplotlib pyplot as pl
  • sqlalchemy.exc.ResourceClosedError: This result object does not return rows.

    向数据库插入数据时 报错对象没有返回 已被自动关闭 参考 http t csdn cn Ry6zS 把SQLAlchemy版本换成1 3解决
  • 数据库断连后如何重新获得数据库连接

    前提 DBPool连接池自身有数据库断连后获取重连的机制 问题 执行某条sql时连接断开 此时此条sql不会被执行 并且若不进行特殊处理 程序会继续往下执行 此时会出现数据丢失现象 解决思路 1 判断是否是因为连接被断开引起的异常 2 若是
  • 小程序的开发之使用SVG

    昨天突然提出要在小程序中使用SVG 因为我们的小程序项目是有主题色的 不同的主题色时有些图片一直是固定的 显的有些格格不入 所以打算使用SVG来实现根据主题色的颜色进行变化 什么是SVG SVG是 Scalable Vector Graph
  • JS setInterval()/setTimeout()——实现动态时间,倒计时

    一 动态时间 1 setInterval 实现 html部分 div div
  • Design Compiler (十)——其他的时序约束选项(一)

    之前讲了基本的时序路径约束 现在我们来看一下其他的约束 然后通过实战来讲解一些其他的约束 实战中也没有前面的 理论 中的约束类型 但是可以通过实战来了解其他的约束 本文的具体内容是 多时钟同步约束 门控时钟的约束 实战 正负边沿触发器的约束
  • 突破人生的瓶颈(心灵之灯)

    人生 四度 平时除了看新闻外我很少看电视 但是那天除外 那天晚上写完稿子 随意打开了一个频道 是央视三套的艺术人生 为何庆魁加油 我不喜欢主持人以煽情的方式 不停发掘主人公内心伤痛泪水的惯用风格 本想换台 考虑到剧作家何庆魁今年来家庭遇到的
  • 微服务架构跨库分页解决的四种方案

    微服务架构是一项在云中部署应用和服务的新技术 大部分围绕微服务的争论都集中在容器或其他技术是否能很好的实施微服务 而红帽说API应该是重点 微服务可以在 自己的程序 中运行 并通过 轻量级设备与HTTP型API进行沟通 关键在于该服务可以在
  • HTTP请求的8种请求方式以及常见的HTTP状态码总结

    完整的HTTP状态码见 菜鸟教程 HTTP8种请求方式的原文 HTTP的8种请求方式的简单介绍 目录 一 HTTP请求的8种请求方式 二 什么是HTTP状态码 三 HTTP状态码的分类 一 HTTP请求的8种请求方式 序号 方法 描述 1
  • python批量检索文献_导师每天都让查文献,如何才能快速查找文献呢?

    最近在后台有很多朋友留言 导师每天都让我查文献 但现在网上收录的文献这么多 每次都要花好长的时间 我该怎么办 作为研究人员 大家很多时候对于文献检索 数据分析等问题都感到很崩溃 如果采用常规的人工搜索 软件整理 往往要花费大量的时间 明明是
  • 自定义vue组件--实现多图片上传

    一 引入 文件上传在日常的开发中是一项基本的操作 在前端中得以广泛的使用 因此将其封装成一个组件显得极为重要 本文主要是基于vue实现的自定义多图片上传组件 二 自定义vue上传组件 MultiUpload组件的封装