vue + vuedraggable 实现拖拽上传图片预览删除功能

问题:vue2+el-upload组件上传的图片 实现图片拖拽

 第一段代码整洁使用 需要先下载vuedraggable插件 npm i vuedraggable

// 简单来说 拖拽上传 
<draggable v-model="pictureUrl">
          <li
            v-for="(item, index) in pictureUrl"
            :key="item.address"
            class="el-upload-list__item is-success animated"
          >
            <img
              :src="item.address"
              alt=""
              class="el-upload-list__item-thumbnail"
            />
            <i class="el-icon-close"></i>
            <span class="el-upload-list__item-actions">
              <!-- 预览 -->
              <span
                class="el-upload-list__item-preview"
                @click="handlePictureCardPreviewFileDetail(item)"
              >
                <i class="el-icon-zoom-in"></i>
              </span>
              <span
                class="el-upload-list__item-delete"
                @click="handleRemoveFileDetail(item, index)"
              >
                <i class="el-icon-delete"></i>
              </span>
            </span>
          </li>
        </draggable>
// 样式自己调一下就行 
// :show-file-list="false"这个属性需要加 不走el-upload默认的列表
<el-upload :show-file-list="false">

<script>
  import draggable from "vuedraggable"; 
// 导入组件 然后 就能实现图片拖拽了 预览 和 删除 相信你们 不需要写了
</script>
<template>
  <div>
    <div class="ac-image-upload" :style="{ width: width }">
      <ul class="el-upload-list el-upload-list--picture-card">
        <draggable v-model="pictureUrl">
          <li
            v-for="(item, index) in pictureUrl"
            :key="item.address"
            class="el-upload-list__item is-success animated"
          >
            <img
              :src="item.address"
              alt=""
              class="el-upload-list__item-thumbnail"
            />
            <i class="el-icon-close"></i>
            <span class="el-upload-list__item-actions">
              <!-- 预览 -->
              <span
                class="el-upload-list__item-preview"
                @click="handlePictureCardPreviewFileDetail(item)"
              >
                <i class="el-icon-zoom-in"></i>
              </span>
              <span
                class="el-upload-list__item-delete"
                @click="handleRemoveFileDetail(item, index)"
              >
                <i class="el-icon-delete"></i>
              </span>
            </span>
          </li>
        </draggable>
      </ul>
      <el-upload
        :disabled="disabled"
        v-if="multiple"
        :limit="limit"
        multiple
        :action="defaultAction"
        :headers="headers"
        :data="upData"
        list-type="picture-card"
        accept="image/jpeg,image/jpg,image/png"
        :on-preview="handlePictureCardPreview"
        :on-remove="handleRemove"
        :on-success="handleSuccess"
        :before-upload="beforeUpload"
        :on-exceed="onExceed"
        :file-list="urlList"
        :show-file-list="false"
        :class="{ hide_box: upload_btn }"
      >
        <i v-if="multiple" class="el-icon-plus"></i>
      </el-upload>
      <el-upload
        v-else
        class="upload-demo"
        multiple
        :action="defaultAction"
        :headers="headers"
        :on-preview="handlePreview"
        :data="upData"
        :file-list="urlList"
      >
        <!--       <div slot="tip" class="el-upload__tip">
        只能上传word/execl/PDF文件,且不超过500kb
      </div> -->
        <div slot="file" slot-scope="{ file }" style="font-size: 18px">
          <span>{{ file.name }}</span>
          <i
            class="el-icon-download"
            style="margin-left: 20px; cursor: pointer"
            @click="downFile(file)"
          />
        </div>
      </el-upload>
    </div>
    <el-dialog :visible.sync="dialogVisible" append-to-body title="图片预览">
      <div
        class="box-card"
        style="
          display: flex;
          align-items: center;
          justify-content: center;
          min-height: 50vh;
        "
      >
        <img style="max-width: 100%" :src="dialogImageUrl" alt="" />
      </div>
    </el-dialog>
    <el-dialog
      title="附件预览"
      v-if="fileUrlVisible"
      :visible.sync="fileUrlVisible"
      :showFooter="false"
      append-to-body
      height="800px"
    >
      <iframe
        sandbox="allow-scripts allow-top-navigation allow-same-origin allow-popups"
        :src="maskObj.url"
        frameborder="0"
        style="z-index: 1000; height: 560px; width: 100%"
      >
      </iframe>
      <!--      <iframe
        :src="dialogFileUrl"
        width="100%"
        height="100%"
        border="0"
      ></iframe> -->
    </el-dialog>
    <div
      style="font-size: 12px; color: #999999; margin-top: 10px"
      v-if="!upload_btn"
    >
      <div style="color: red" v-if="isBatch">*批量编辑图片将清空原有图片</div>
      <span v-if="limit > 1"> 最多可以上传{{ limit }}张图片;</span
      >可上传jpg、jpeg、png文件,且单张不超过5M
    </div>
    <div v-else-if="upload_btn && urlList.length === 0">
      <span>未上传任何{{ this.multiple ? "图片" : "附件" }}!</span>
    </div>
  </div>
</template>
import draggable from "vuedraggable";
export default {
  props: {
    width: {
      type: String,
      default: "100%",
    },
    disabled: {
      type: Boolean,
      default() {
        return false;
      },
    },
    url: {
      type: [Array, String],
      default() {
        return [];
      },
    },
    isRequested: {
      type: Boolean,
      default: false,
    },
    action: {
      type: String,
      default: "",
    },
    limit: {
      type: Number,
      default: 9,
    },
    multiple: {
      type: Boolean,
      required: true,
    },
    isBatch: Boolean,
  },
  components: {
    draggable,
  },
  data() {
    return {
      dialogImageUrl: noPhoto,
      noPhotoSrc: noPhoto,
      dialogVisible: false,
      upData: {
        type: "image",
      },
      src: "",
      urlList: [],
      imgHeader: localStorage.getItem("file_domain") || "",
      dialogFileUrl: "",
      fileUrlVisible: false,
      maskObj: {
        flag: false,
        url: "",
      },
      pictureUrl: [],
    };
  },
  computed: {
    defaultAction() {
      return (
        this.action || "http://192.168.1.30:8090/ohd/specialist/minio/upload"
      );
    },
    headers() {
      return {
        "X-Access-Token": getToken(),
      };
    },
    // 判断只允许单张上传图片时,图片是否已经上传
    isImgUpload() {
      return this.dialogImageUrl === this.noPhotoSrc;
    },
    upload_btn() {
      return this.limit === this.urlList.length;
    },
  },
  created() {
    this.getUrl();
    if (this.multiple) {
      // console.log();
      this.urlList = this.url.map((item) => {
        return {
          name: "file",
          url: this.imgHeader + item,
        };
      });
    } else if (this.url) {
      // this.dialogImageUrl = this.imgHeader + this.url;
      this.urlList = this.url;
    }
  },
  mounted() {},
  updated() {
    this.getUrl();
  },
  methods: {
    getUrl() {
      this.pictureUrl = this.url;
    },
    updateList(e) {
      const newIndex = e.newIndex; // 新位置下标
      const oldIndex = e.oldIndex; // 原始位置下标
      // 打印出新位置 位置从0开始算
    },
    handlePictureCardPreviewFileDetail(file) {
      console.log(this.url);
      this.dialogImageUrl = file.address;
      this.dialogVisible = true;
    },
    // 删除
    handleRemoveFileDetail(item, index) {
      console.log(item, index);
      this.url.splice(index, 1);
    },
    // 最大上传张数
    onExceed(file, fileList) {
      this.$message.warning(`上传图片不超过${this.limit}张`);
    },
    // 删除
    handleRemove(file, fileList) {
      this.$emit("delUrl", file, fileList);
    },
    // 预览
    handlePictureCardPreview(file) {
      this.dialogImageUrl = file.url;
      this.dialogVisible = true;
    },
    // 阻止upload的自己上传,进行再操作
    beforeUpload(file) {
      const isLt2M = file.size / 1024 / 1024 < 5;
      if (!isLt2M) {
        // 图片大小大于5MB
        this.$message.error("上传图片大小不能超过 5MB!");
        return false;
      }
    },
    uploadClick() {
      this.$emit("onClick");
    },
    // 只允许上传单张图片时删除 图片
    deleteUrl() {
      this.dialogImageUrl = noPhoto;
      this.$emit("delUrl");
    },
  handleSuccess(response, file, fileList) {
      if (this.multiple) {
        this.pictureUrl.push(file["response"].data);
        // this.$emit("onSuccess", file);
      } else {
        if (isSuccess(response.code)) {
          this.dialogImageUrl = file.url;
          this.pictureUrl.push(file["response"].data);
          // this.$emit("onSuccess", file);
        } else {
          this.dialogImageUrl = noPhoto;
          this.$message.error(response.msg);
        }
      }
    },
    // 预览文件
    handlePreview(file) {
      console.log(file);
    },
    // 下载文件
    downFile(file) {
      window.location.href = file.url;
    },
  },
  watch: {
    isRequested: {
      handler() {
        this.urlList = this.url.map((item) => {
          return {
            name: "file",
            url: localStorage.getItem("file_domain") + item,
          };
        });
      },
      deep: true,
      immediate: true,
    },

    // 如果传进来的url为空,那么清空已经存在的图片
    url(val) {
      if (val && !val.length) {
        this.urlList = [];
      }
      // else {
      //   this.urlList = val.map((item) => {
      //     if (typeof item === "string") {
      //       return {
      //         name: "file",
      //         url: this.imgHeader + item,
      //       };
      //     } else {
      //       return {
      //         name: "file",
      //         url:
      //           this.imgHeader +
      //           `${decodeURIComponent(item.address)}${decodeURIComponent(
      //             item.path
      //           )}`,
      //       };
      //     }
      //   });
      // }
    },
    pictureUrl: {
      handler(value) {
        this.$emit("update:url", value);
      },
      immediate: true,
    },
  },
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值