基于elementUI实现图片上传拖拽排序组件

背景:

elementUI 上传文件组件不支持多张图片同时上传实现排序。必须一张一张上传。影响用户体验

解决方案:

方案1:
同时上传图片的时候,在图片名称加上时间戳,上传成功之后,在根据时间戳排序。
会产生的问题:1、时间戳有时候会相同。2、顺向排序勉强实现,但想替换中间一张图片就有困难。
方案2:拖拽排序,自行拖拽排序,灵活性比较高,没有啥限制。(可以使用

实现:

1、借助第三方拖拽组件vuedraggable

npm install vuedraggable --save

import draggable from 'vuedraggable'
 components: {
    draggable
  },

2、封装文件上传组件

<draggable v-if="type === 'picture-drag'" :value="fileList" :animation="100" style="position: relative;margin-bottom: 10px; clear: left" @input="onDraggable">
      <div v-for="(item, index) in fileList" :key="index" style="display: inline-block;float: left" class="isimages">
        <div
          :style="{ width: width, height: height, borderRadius: 5 + 'px' }"
          style="background: white;"
        >
          <img
            ref="preview"
            z-index="999"
            lazy
            :loading="true"
            :style="{ width: width, height: height, borderRadius: 5 + 'px' }"
            :src="item.url"
          >
          <div class="imgs_prews">
            <div
              class="imgs_prew"
              :style="{ width: width, height: height, borderRadius: 5 + 'px' }"
            >
              <i class="el-icon-zoom-in" @click="handlePictureCardPreview(item)" />
              <span />
              <i class="el-icon-delete" @click="handleRemove(item)" />
            </div>
          </div>
        </div>
      </div>
      <el-upload
        style="display: inline-block"
        action="#"
        :class="(fileList && fileList.length < limit)?'':'picture-uploader'"
        list-type="picture-card"
        class="picture-card"
        :auto-upload="false"
        :multiple="multiple || limit > 1"
        :disabled="disabled"
        :style="{'--height':height,'--width':width}"
        :on-change="handlePictureChange"
        :on-preview="handlePicturePreview"
        :on-exceed="handleExceed"
        :file-list="[]"
        :limit="limit - fileList.length"
      >
        <div slot="default" style="position: relative;margin-top: -10px">
          <i v-if=" fileList && fileList.length < limit" class="el-icon-plus" />
          <div class="limit-num">{{ fileList && fileList.length }}/{{ limit }}</div>
        </div>
      </el-upload>
    </draggable>


部分核心代码,方法自行实现。需要的prop如下

props: {
    value: {
      type: [Array, String],
      default() {
        return []
      }
    },
    disabled: {
      type: Boolean,
      default: false
    },
    multiple: {
      type: Boolean,
      default: false
    },
    limit: {
      type: Number,
      default: 5
    },
    width: {
      type: String,
      default: '96px'
    },
    height: {
      type: String,
      default: '96px'
    },
    filePath: {
      type: String,
      default: 'pc/'
    },
    type: {
      type: String,
      default: () => ''
    },
    fileType: {
      type: Array,
      default: () => [] // [.png]
    },
    fileSize: {
      type: String,
      default: () => '2'
    }
  },

css代码:


. isimages {
  position: relative;
  display: inline-block;
  margin-right: 8px;
}

. isimages:hover .imgs_prews {
  display: block;
}

.imgs_prews {
  display: none;
}

.imgs_prew {
  position: absolute;
  top: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  color: #fff;
  background: rgba(0, 0, 0, .3);
}

.imgs_prew I {
  display: inline-block;
  font-size: 20px;
  cursor: pointer;
}

.imgs_prew span {
  width: 2px;
  height: 18px;
  margin: 0 8px;
}

说明:这里有个关于v-model的问题。如果draggable使用v-model,在fileList的值是父视图传过来的,那么是无法更改父组件的值。所以用value赋值,@input自行处理事件

效果:

image.png

效果和elementUI的样式是一致的。区别只是一个可以拖拽一个不可以

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值