vue3+ant-design+vite实现input框粘贴图片或者文本上传

484 阅读1分钟

vue3+ant-design+vite实现input框粘贴图片或者文本上传,图片上传

背景

需求背景是用户粘贴截图或者复制的图片后,需要自动上传文件到阿里云。

实现思路

利用input输入自带的方法paste。根据文件类型来判定是不是图片,如果是图片就把文件上传到阿里云。

<template>
  <div class="main">
    <a-textarea
      :rows="2"
      placeholder="粘贴图片即上传附件"
      v-model="textarea"
      @paste="handlePaste"
    />
    <a-upload
      class="upload-demo"
      :action="uploadUrl"
      :onPreview="handlePreview"
      :beforeRemove="beforeRemove"
      :onRemove="handleRemove"
      listType="picture-card"
      :multiple="true"
      :limit="3"
      :fileList="fileList"
      @exceed="handleExceed"
    >
      <div>
        <a-button> <a-icon type="upload" /> 上传 </a-button>
      </div>
    </a-upload>
  </div>
</template>

<script>
import { ref, reactive } from "vue";

export default {
  setup() {
    const fileList = ref([
      {
        uid: "-1",
        name: "food.jpeg",
        url: "https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100",
      },
      {
        uid: "-2",
        name: "food2.jpeg",
        url: "https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100",
      },
    ]);
    const textarea = ref("");
    const uploadUrl = ref("https://your-upload-url.com"); // Replace with your upload endpoint

    const handleRemove = (file) => {
      return new Promise((resolve) => {
        setTimeout(() => {
          const index = fileList.value.findIndex(
            (item) => item.uid === file.uid
          );
          fileList.value.splice(index, 1);
          resolve();
        }, 500);
      });
    };

    const handlePreview = (file) => {
      console.log(file);
    };

    const beforeRemove = (file) => {
      return new Promise((resolve) => {
        return window.confirm(`确定删除 ${file.name} 吗?`);
      });
    };

    const handleExceed = (files, fileList) => {
      window.alert(
        `当前限制选择 3 个文件,本次选择了 ${files.length} 个文件,共选择了 ${
          files.length + fileList.value.length
        } 个文件`
      );
    };

    const handlePaste = async (e) => {
      const items = e.clipboardData.items;
      console.log("items", items);
      let file = [];
      for (let i = 0; i < items.length; i++) {
        if (items[i].type.includes("image")) {
          file.push(items[i].getAsFile());
        }
      }

      console.log(file, "file");

      if (file) {
        //  This is where you'd handle the actual upload
        const formData = new FormData();
        formData.append("file", file);
        try {
          const response = await fetch(uploadUrl.value, {
            method: "POST",
            body: formData,
          });
          const data = await response.json(); // Adapt to your backend response
          fileList.value.push({
            uid: Date.now(),
            name: file.name,
            url: data.url, // Assuming your backend returns the URL
          });
        } catch (error) {
          console.error("Upload failed:", error);
          window.alert("图片上传失败");
        }
      }
    };

    return {
      fileList,
      textarea,
      handleRemove,
      handlePreview,
      beforeRemove,
      handleExceed,
      handlePaste,
      uploadUrl,
    };
  },
};
</script>

<style scoped>
.main {
  margin: 50px 200px;
}
.upload-demo {
  margin-top: 30px;
}
</style>