vue上传多张图片,可删除、可拖拽位置

需求:
vue后台项目实现图片上传;
在这里插入图片描述

在这里插入图片描述

代码:
先安装组件
在这里插入图片描述

<el-form-item label="轮播图">
            <div v-if="imageListArr.length != 0" class="mainDrawing">主图</div>
            <div class="draggableBox">
              <draggable v-model="imageListArr" @update="datadragEnd(0)">
                <transition-group>
                	<!-- 使用 before-upload 限制用户上传的图片格式和大小。上传文件之前的钩子,参数为上传的文件
                       http-request覆盖默认的上传行为,可以自定义上传的实现-->
                  <div class="mh-up-w" v-for="(item, idx) of imageListArr" @click="setItemIdx(idx, 0)" :key="item.imgUrl">
                    <el-upload class="avatar-uploader" action="" :show-file-list="false"
                      :before-upload="imageUploadRegForMore" :http-request="emitUploadForMore">
                      <div v-loading="detailImageUploadLoading && currentUpFileIdx == idx">
                        <img v-if="item.imgUrl" :src="item.imgUrl" class="avatar">
                        <i v-else class="el-icon-plus avatar-uploader-icon"></i>
                      </div>
                    </el-upload>
                    <div class="mh-up-h-w" v-if="item.imgUrl && item.imgUrl != ''">
                      <span class="up-h-i" @click="deleteUpFile(idx, 0)"><i class="el-icon-delete"></i></span>
                      <span class="up-h-i"><i class="el-icon-rank"></i></span>
                    </div>
                  </div>
                </transition-group>
              </draggable>
              <div class="tip-txt-w">
                <span>提示:支持JPG或PNG两种格式,图片大小不超过1M;最多上传10张;拖动调整顺序;默认第一张图为主图;上传商品图片同步全区域。</span>
              </div>
            </div>
          </el-form-item>


<script>
	import Draggable from 'vuedraggable'
	data() {
		return {
			// 商品图临时使用  imgUrl: 图片地址  sortNum: 序号
      		imageListArr: [
        		{
         			imgUrl: '',
         			sortNum: ''
        		}
      		],
      		detailImageUploadLoading: false,
      		currentUpFileIdx: -1,
		}
	},
	components: {
    	'draggable': Draggable,
  	},
methods: {
		/**
     * [datadragEnd 拖拽结束]
     * @return {[type]} [description]
     */
     datadragEnd (evt) {
     	// 拖拽图片更换位置 并重新从1开始排序
        this.imageListArr.forEach((item, index) => {
          item.sortNum = index + 1
        })
        this.imageListArr = this.imageListArr.filter(item => {
          return item.imgUrl != ''
        });
        let imageListItem = {
          imgUrl: '',
          sortNum: ''
        }
        this.imageListArr.push(imageListItem)
    },
    // 设置当前选中索引
    setItemIdx (idx, type) {
      if (this.detailImageUploadLoading) return
      this.currentUpFileIdx = idx
    },
    // 删除当前图片
    deleteUpFile (_idx, type) {
      this.$confirm('确定删除当前图片吗?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        })
          .then(() => {              
          	  this.imageListArr = this.imageListArr.filter((item, idx) => {
                return idx != _idx
              })
              this.imageListArr.forEach((item, index) => {
                item.sortNum = index + 1
              })
          })
    },
    // 校验上传图片格式大小
    imageUploadRegForMore (file) {
      const isPic = file.type.indexOf('image/') !== -1
      const isJPG = (file.type === 'image/jpeg' || file.type === 'image/png')
      const isSizeNum = file.size <= 1 * 1024 * 1024
      if (!isPic) {
        this.$message.error('支持JPG或PNG两种格式,图片大小不超过1M;最多上传10张;拖动调整顺序;上传商品图片同步全区域。')
        return false
      }
      if (!isJPG) {
        this.$message.error('支持JPG或PNG两种格式,图片大小不超过1M;最多上传10张;拖动调整顺序;上传商品图片同步全区域。')
        return false
      }
      if (!isSizeNum) {
        this.$message.error('支持JPG或PNG两种格式,图片大小不超过1M;最多上传10张;拖动调整顺序;上传商品图片同步全区域。')
        return false
      }
      return isPic && isJPG && isSizeNum
    },
    // 上传到服务器,并对图片数组做处理
    emitUploadForMore (e) {
      if (this.imageListArr.length > 10 && this.currentUpFileIdx != -1) {
        this.$message.error('最多可添加10张')
        return
      }
      this.detailImageUploadLoading = true
      let loginInfo = Storage.get('loginInfo') || {}
      let formdata = new FormData()
      let file = e.file
      formdata.append('file', file)
      this.$http.post(url.goodsMgt.uploadFile + '?baseDir=web/bazzarIcon&fileType=img&systemName=bazzar_web', formdata, {
        headers: {
          'Content-Type': 'multipart/form-data',
          'Authorization': `${loginInfo.token_type} ${loginInfo.access_token}`
        }
      })
        .then((res) => {
          this.detailImageUploadLoading = false
          let urlImage = res.data.url;
          this.setImgUrl(this.currentUpFileIdx, urlImage, 0)
          if (this.currentUpFileIdx != -1) {
            let hash = {}
            let imageListItem = {
              // imgType: 22,
              imgUrl: '',
              sortNum: ''
            }
            this.imageListArr.push(imageListItem)

            // 去重  防止多个空对象
            this.imageListArr = this.imageListArr.reduceRight((item, next) => {
              hash[next.imgUrl] ? '' : hash[next.imgUrl] = true && item.push(next)
              return item
            }, [])
            this.imageListArr.reverse()
          }
        })
        .catch((err) => {
          this.detailImageUploadLoading = false
        })
    },
    // 将上传的图片放入数组里
    setImgUrl (_idx, _imgUrl, type) {
        let urlImage = _imgUrl
        let currentIdx = _idx
        this.imageListArr.forEach((item, index) => {
          if (index === currentIdx) {
            this.imageListArr[index].imgUrl = urlImage
            this.imageListArr[index].sortNum = parseInt(currentIdx) + 1
          }
        })
    },
	
	// 获取详情
	getGoodsDetail(id) {
      this.$http.post(url.goodsMgt.goodsDetail, { id }).then((res) => {
        if (res.code == 0) {
          this.goodsInfo = res.data,
          this.imageListArr = res.data.goodsSquareImgList || []
          let imageListItem = {
            imgUrl: '',
            sortNum: ''
          }
          // 初始化图片,将空塞入最后一项作为➕号展示
          this.imageListArr.push(imageListItem)
        }
      })
    },
    // 保存
    save() {
      this.goodsInfo.goodsSquareImgList = this.imageListArr.filter(item => {
        return item.imgUrl
      })
      this.$http
        .post(url.goodsMgt.updateGoods, {
          ...this.goodsInfo,
          id: this.id
        })
        .then((response) => {
          this.loading = false
          if (response.code === 0) {
            this.$notify.success('保存成功')
            this.back()
            return
          }
          throw new Error(response.msg)
        })
        .catch((e) => {
          this.loading = false
          this.$message.error(e.message)
        })
    },
}
</script>
<style>
/* 轮播图 */
/* @import '../../../../assets/file_upload.css'; */
.mh-up-w {
  float: left;
  margin-left: 10px;
}
.mh-up-w:first-child {
  margin-left: 0;
}
.mh-up-h-w {
  padding: 0 5px;
  line-height: 0;
  margin-top: -8px;
  margin-bottom: 8px;
  text-align: center;
}
.up-h-i {
  cursor: pointer;
  padding-left: 6px;
  padding-right: 6px;
}
.up-h-i:hover {
  color: #3080fe;
}
.draggableBox {
  width: 600px;
}
.avatar-uploader {
  width: 110px;
  height: 110px;
  display: inline-block;
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}
/* .tip-txt-w {
  display: inline-block;
  margin-left: 10px;
  vertical-align: top;
} */
.avatar-uploader:hover {
  border-color: #409EFF;
}
</style>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值