vue2+elementUI+vuedraggable图片上传后可拖曳排序

安装vue-draggable
npm i -S vuedraggable
子组件DragUpload.vue
<template>
  <div>
    <draggable
      v-model="uploadList"
      @update="datadragEnd"
      @start="drag = true"
      @end="drag = false"
    >
      <div class="img-wrapper" v-for="(item, index) in uploadList" :key="index">
        <el-image :src="item" :key="imageKey"></el-image>
        <div class="operate-wrap" :title="'拖曳图片可排序'">
          <div class="operate-bg"></div>
          <span class="icon-row">
            <i class="el-icon-delete" @click="handleRemove(index)"></i>
            <i class="el-icon-zoom-in" @click="handlePictureCardPreview(item)"></i>
          </span>
        </div>
      </div>
    </draggable>
    <el-upload
      :action="ishttps + '//XXXX.XXXXX.com/'"
      list-type="picture-card"
      :before-upload="handleBefore"
      :on-success="handleSuccess"
      :on-error="handleError"
      :data="qiniuUploadDatas"
      :accept="accepts"
      title="点击上传"
      multiple
      v-show="uploadList.length < allListLen"
    >
      <i class="el-icon-plus"></i>
    </el-upload>

    <el-dialog :visible.sync="dialogVisible">
      <img width="100%" :src="dialogImageUrl" alt="" />
    </el-dialog>
  </div>
</template>
<script>
import draggable from "vuedraggable";
import api from "../../api/index";
export default {
  name: "drag-upload",
  props: {
    // 图片路径
    allList: {
      type: Array,
      default() {
        return [];
      },
    },
    // 图片文件大小
    imgSize: {
      type: Number,
      default: 10,
    },
    // 最大上传数量
    allListLen: {
      type: Number,
      default: 5,
    },
    // 可上传的文件格式
    accepts: {
      type: String,
      default:
        "image/gif,image/jpeg,image/jpg,image/JPG,image/JPEG,image/png,image/svg,image/ico",
    },
  },
  components: {
    draggable,
  },
  data() {
    return {
      dialogImageUrl: "",
      dialogVisible: false,
      uploadList: [],
      qiniuUploadDatas: {},
      drag: false,
      imageKey: 0,
      ishttps: "",
      flag: 0,
    };
  },
  created() {
    this.ishttps = document.location.protocol;
  },
  methods: {
    handleRemove(index) {
      this.flag = 0;
      this.uploadList.splice(index, 1);
      this.$emit("allList", this.uploadList);
    },
    handlePictureCardPreview(file) {
      this.dialogImageUrl = file;
      this.dialogVisible = true;
    },
    handleBefore(file) {
      const type = this.accepts;
      if (!type.includes(file.type)) {
        alert(`请上传${this.accepts}类型文件`);
        return false;
      }
      const isLtM = file.size / 1024 / 1024 < this.imgSize;
      if (!isLtM) {
        alert(`图片大小不超过${this.imgSize}M`);
        return false;
      }
      return api.getQiniuToken().then((res) => {
        // 配置上传的七牛token
        this.qiniuUploadDatas = {
          token: res.retInfo,
          name: file.name,
          key: new Date().getTime() + "-" + file.name,
        };
      });
    },
    handleSuccess(res) {
      if (this.uploadList.length >= this.allListLen) {
        this.flag++;
        if (this.flag == 1) {
          alert("最多可上传" + this.allListLen + "张图片");
        }  
        return false;
      }
      this.flag = 0;
      const url = "https://XXXX.XXXXX.com/" + res.retInfo;  // 拼接七牛云的图片路径
      this.imageKey++;
      this.uploadList.push(url);
      this.$emit("allList", this.uploadList);
    },
    handleError(error) {
      if (error.status == 614) {
        alert("七牛云上已存在相同名称图片");
        return false;
      } else {
        alert(JSON.stringify(error));
        return false;
      }
    },
    // 拖动排序
    datadragEnd() {
      this.$emit("allList", this.uploadList);
    },
  },
  watch: {
    allList: {
      handler: function (val) {
        this.uploadList = val;
      },
      immediate: true,
      deep: true,
    },
  },
};
</script>
<style lang="less" scoped>
.img-wrapper {
  float: left;
  position: relative;
  margin-right: 20px;
  margin-bottom: 20px;
  border-radius: 6px;
  width: 148px;
  height: 148px;
  overflow: hidden;

  &:hover {
    .operate-wrap {
      display: block;
    }
  }
}

.operate-wrap {
  display: none;
}

.operate-bg {
  background: #000000;
  width: 148px;
  height: 148px;
  opacity: 0.4;
  position: absolute;
  top: 0;
  left: 0;
  z-index: 8;
}

.icon-row {
  position: absolute;
  top: 0;
  left: 0;
  display: flex;
  flex-direction: row;
  align-items: center;
  font-size: 25px;
  color: #ffffff;
  z-index: 10;
  width: 100%;
  height: 100%;
  justify-content: center;

  i {
    margin: 0 10px;
  }
}
/deep/.el-upload-list__item {
  display: none;
}
</style>

子组件Upload.vue
<template>
  <div>
    <div class="upload-wrap">
    <!-- 编辑/查看时图片显示 -->
      <div ref="ShowImg" v-if="imgUrl">
        <div class="img-wrapper">
          <el-image :src="imgUrl"></el-image>
          <div class="operate-wrap">
            <div class="operate-bg"></div>
            <i class="el-icon-delete del-icon" @click="deleImg()"></i>
            <i class="el-icon-zoom-in preview-icon" @click="handlePreview()"></i>
          </div>
        </div>
      </div>
	  <!-- 新增时 点击上传图片 -->
      <el-upload list-type="picture-card" :multiple='multiple' action="http://xxxx.xxxx.com/" :data="qiniuUploadForm" :on-preview="handlePictureCardPreview" :on-remove="handleRemove" :on-error="handleImageError" :on-success="handleCoverSuccess" :before-upload="beforeCoverUpload" accept=".gif,.jpeg,.jpg,.JPG,.JPEG,.png,.svg,.ico" title="点击上传">
        <i class="el-icon-plus"></i>
      </el-upload>
    </div>
    <!-- 弹框显示原图 -->
    <el-dialog :visible.sync="dialogVisible">
      <img width="100%" :src="childImg||imgUrl" alt="">
    </el-dialog>
    <!-- 提示性文本 -->
    <div class="row">
      <div slot="tip" class="el-upload__tip" style="line-height:24px;color:#999999">
        <slot name="advise-tip"></slot>
      </div>
    </div>

  </div>
</template>
<script>

export default {
  props: {
    imgUrl: String,
  },
  data() {
    return {
      childImg: '',
      qiniuUploadForm: {}, // 七牛图片的上传对象
      dialogVisible: false,
      multiple: false,
    }
  },
  methods: {
    // 上传图片成功
    handleCoverSuccess(res) {
      this.childImg = "https://XXXX.com/" + res.retInfo;
      this.$emit('childImg', this.childImg);
    },
    // 上传图片失败
    handleImageError(err, file) {
      if (err.status == 614) {
        this.$message.error("七牛云上已存在同名称图片!");
      } else {
        this.$message.error(JSON.stringify(err));
      }     
    },
    beforeCoverUpload(file) {
      const isLt1M = file.size / 1024 / 1024 < 1;
      if (!isLt1M) {
        this.$message.error('图片大小不超过1M');
        return;
      }
      return api.getQiniuToken().then((res) => { // 这里需要配置自己的七牛云api接口
        // 配置上传的七牛token
        this.qiniuUploadForm = {
          token: res.retInfo,
          name: file.name,
          key: Math.floor(Math.random() * 10 + 1) + file.name,
        };
      });
    },

    handleRemove(file) {
      console.log(file);
    },
    handlePictureCardPreview(file) {
      this.childImg = file.url;
      this.$emit('childImg', this.childImg);
      this.dialogVisible = true;
    },
    // 删除图片
    deleImg() {
      this.childImg = '';
      this.$refs.ShowImg.innerHTML = "";
      this.$emit('childImg', this.childImg);
    },
    // 预览
    handlePreview() {
      this.dialogVisible = true;
    },
  },
}
</script>
<style lang="less" scoped>
.upload-wrap {
  max-width: 150px;
  overflow: hidden;
  white-space: nowrap;
  & > div {
    display: inline-block;
    vertical-align: middle;
  }
}
.img-wrapper {
  position: relative;
  margin-right: 20px;
  margin-bottom: 20px;
  border: 1px dashed #c0ccda;
  border-radius: 6px;
  width: 148px;
  height: 148px;
  overflow: hidden;
  &:hover {
    .operate-wrap {
      display: block;
    }
  }
}
.operate-wrap {
  display: none;
}
.operate-bg {
  background: #000000;
  width: 148px;
  height: 148px;
  opacity: 0.4;
  position: absolute;
  top: 0;
  left: 0;
  z-index: 8;
}
.del-icon {
  position: absolute;
  top: 0;
  right: 36px;
  font-size: 25px;
  line-height: 142px;
  color: #ffffff;
  z-index: 10;
}
.preview-icon {
  position: absolute;
  top: 0;
  left: 36px;
  font-size: 25px;
  line-height: 142px;
  color: #ffffff;
  z-index: 10;
}
</style>

父页面 Home.vue
<template>
  <div style="margin:40px">
    <el-form :model="ruleForm" ref="ruleForm" label-width="126px">
      <el-row style="width:980px">
        <el-col :span="24">
          <div class="grid-content bg-purple-dark">
            <el-form-item label="上传图片:" prop="imgUrl" class="avatar-item">
              <div class="row">
                <Upload :imgUrl="ruleForm.imgUrl" v-on:childImg="childImgUrl">
                  <p slot="advise-tip">图片大小不超过1M</p>
                </Upload>
              </div>
            </el-form-item>
            <el-form-item label="图片可拖曳排序:" prop="trialImgs">
              <div class="row">
                <DragUpload :allList="ruleForm.trialImgs" v-on:allList="trialImgs">
                </DragUpload>
                <div class="el-upload__tip gray-tip">每张图片大小不超过10M</div>
              </div>
            </el-form-item>
            <el-form-item>
              <el-button type="primary" @click="submitForm('ruleForm')" v-show="!edit">保存</el-button>
            </el-form-item>
          </div>
        </el-col>
      </el-row>
    </el-form>
  </div>

</template>
<script>
import Upload from "../components/Upload";
import DragUpload from '../components/DragUpload';  // 引入vue-draggable

export default {
  data() {
    return {
      name: "Home",
      ruleForm: {
        imgUrl: '',
        trialImgs: [],
      },
      dialogImageUrl: '',
      dialogVisible: false,
    };
  },
  components: {
    Upload,
    DragUpload,
  },
  methods: {
    // 上传图片
    childImgUrl(childImg) {
      this.ruleForm.imgUrl = childImg;
    },

    // 图片可拖曳排序
    trialImgs(allList) {
      this.ruleForm.trialImgs = allList
    },
    // 保存
    submitForm(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          // console.log(this.ruleForm) // 所有数据
          let tempRuleForm = JSON.parse(JSON.stringify(this.ruleForm))

          let parmas = {
            "id": this.$route.query.id * 1,
            "imgUrl": tempRuleForm.imgUrl,
            "triaTpicList": tempRuleForm.triaTpicList
          }
          console.log(parmas)
           api.save(parmas).then((res) => {  
             console.log(res)
             alert(res.msg);
           })
        } else {
          console.log('保存失败');
          return false;
        }
      });
    },
    // 获取数据
    getDatas() {
      let that = this;
      let id = this.$route.query.id;
      if (id) {
        api.editDatas(id).then(res => {
          if (res.data) {
            const datas = res.data;
            that.ruleForm = {
              "imgUrl": datas.imgUrl,
              "trialImgs": datas.trialImgs,
            }
            console.log(that.ruleForm)
          }
        })
      }
    },
  }
}
</script>

完整DEMO下载:https://download.csdn.net/download/weixin_45421804/70037592

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值