在 Vue 3 和 TypeScript 项目中,实现文件手动上传、自动上传

不废话直接上代码~~~

-------------------------------------------------------- 手动上传 -----------------------------------------------------------

<template>
  <div>
    <!-- 使用 el-upload 组件,设置 auto-upload 为 false -->
    <el-upload
      ref="upload"
      action="https://jsonplaceholder.typicode.com/posts/"
      :on-change="handleChange"
      :auto-upload="false"
      :file-list="fileList"
    >
      <el-button slot="trigger" type="primary">选择文件</el-button>
    </el-upload>
    <el-button
      style="margin-left: 10px;"
      type="success"
      @click="submitUpload"
      :disabled="!fileList.length"
    >
      手动上传
    </el-button>
  </div>
</template>

<script lang="ts" setup>
import { ref } from 'vue';
import axios from 'axios';
    const upload = ref();
    const fileList = ref([]);
    // 文件变化时触发
    const handleChange = (file: any, fileList: any[]) => {
      console.log('文件变化:', file, fileList);
    };
    // 提交上传
    const submitUpload = () => {
      // 调用组件实例的 submit 方法进行上传
      if (upload.value) {
        upload.value.submit();
      }
    };
});
</script>
<style scoped>
/* 自定义样式 */
</style>
自定义上传逻辑,如果你想更进一步定制上传逻辑(例如使用 Axios 发送请求),你可以监听 http-request 事件,或直接在 submitUpload 方法中处理上传逻辑:
<template>
  <div>
    <el-upload
      ref="upload"
      :auto-upload="false"
      :on-change="handleChange"
      :file-list="fileList"
      :http-request="customUpload"
    >
      <el-button slot="trigger" type="primary">选择文件</el-button>
    </el-upload>
    <el-button
      style="margin-left: 10px;"
      type="success"
      @click="submitUpload"
      :disabled="!fileList.length"
    >
      手动上传
    </el-button>
  </div>
</template>

<script lang="ts" setup>
import { defineComponent, ref } from 'vue';
import axios from 'axios';
 const upload = ref();
    const fileList = ref([]);

    const handleChange = (file: any, fileList: any[]) => {
      console.log('文件变化:', file, fileList);
    };

    const customUpload = async (options: any) => {
      const formData = new FormData();
      formData.append('file', options.file);

      try {
        await axios.post(options.action, formData, {
          headers: { 'Content-Type': 'multipart/form-data' }
        });
        console.log('上传成功');
      } catch (error) {
        console.error('上传失败:', error);
      }
    };

    const submitUpload = () => {
      if (upload.value) {
        // 如果你想逐个上传文件列表中的文件
        fileList.value.forEach((file: any) => {
          customUpload({ action: 'https://jsonplaceholder.typicode.com/posts/', file });
        });
      }
    };
</script>

-------------------------------------------------------- 自动上传 -----------------------------------------------------------

<template>
  <div>
    <!-- 使用 el-upload 组件,并确保 auto-upload 设置为 true -->
    <el-upload
      class="upload-demo"
      action="https://jsonplaceholder.typicode.com/posts/"
      :on-preview="handlePreview"
      :on-remove="handleRemove"
      :before-upload="beforeUpload"
      :on-success="handleSuccess"
      :on-error="handleError"
      :file-list="fileList"
      :headers="headers"
      :data="uploadParams
      multiple
    >
      <el-button type="primary">点击上传</el-button>
      <div slot="tip" class="el-upload__tip">
        只能上传 jpg/png 文件,且不超过 500kb
      </div>
    </el-upload>
  </div>
</template>

<script lang="ts" setup>
import { defineComponent, ref } from 'vue';
import axios from 'axios';
    const uploadParams = reactive({}) // 文件自动上传参数,可选,若不需要参数去掉即可!
    const fileList = ref([]); // 文件列表
    const headers = ref({
      Authorization: 'Bearer your-token-here' // 如果需要,添加认证头信息
    });

    // 文件预览处理函数
    const handlePreview = (file: any) => {
      console.log('预览文件:', file);
    };

    // 文件移除处理函数
    const handleRemove = (file: any, fileList: any[]) => {
      console.log('移除文件:', file, fileList);
    };

    // 上传前钩子函数
    const beforeUpload = (file: File) => {
      const isJPGorPNG = file.type === 'image/jpeg' || file.type === 'image/png';
      const isLt500K = file.size / 1024 < 500;

      if (!isJPGorPNG) {
        ElMessage.error('只能上传 JPG/PNG 文件!');
      }
      if (!isLt500K) {
        ElMessage.error('文件大小不能超过 500KB!');
      }

      return isJPGorPNG && isLt500K;
    };

    // 上传成功回调
    const handleSuccess = (response: any, file: any, fileList: any[]) => {
      console.log('上传成功:', response, file, fileList);
      ElMessage.success('文件上传成功');
    };

    // 上传失败回调
    const handleError = (error: any, file: any, fileList: any[]) => {
      console.error('上传失败:', error, file, fileList);
      ElMessage.error('文件上传失败');
    };

</script>

<style scoped>
.upload-demo {
  margin-top: 20px;
}
</style>

自定义上传逻辑

<template>
  <el-upload
    class="upload-demo"
    :http-request="customUpload"
    :on-preview="handlePreview"
    :on-remove="handleRemove"
    :before-upload="beforeUpload"
    :file-list="fileList"
    :data="uploadParams"
    multiple
  >
    <el-button type="primary">点击上传</el-button>
  </el-upload>
</template>

<script lang="ts">
import { defineComponent, ref } from 'vue';
import axios from 'axios';
const fileList = ref([]);
const uploadParams = reactive({})

    const customUpload = async (options: any) => {
      const formData = new FormData();
      formData.append('file', options.file);

      try {
        await axios.post(options.action, formData, {
          headers: { 'Content-Type': 'multipart/form-data' }
        });
        options.onSuccess?.(); // 调用原生的成功回调
      } catch (error) {
        options.onError?.(error); // 调用原生的错误回调
      }
    };

    // ... 其他事件处理函数 ...

</script>

### 实现Element Plus中多文件选择后手动触发上传 为了实现Element Plus中的多文件选择并手动触发上传,在HTML模板部分定义`el-upload`组件,并设置其属性来控制行为。对于手动上传,需禁用自动上传并将文件列表存储起来以便后续处理。 ```html <template> <div> <!-- 文件上传 --> <el-upload ref="upload" action="" :auto-upload="false" multiple :on-change="handleChange" :file-list="fileList"> <el-button type="primary">导入</el-button> </el-upload> <!-- 提交按钮用于触发实际的上传逻辑 --> <el-button style="margin-left: 10px;" @click="submitUpload">提交</el-button> </div> </template> ``` 在上述代码片段中,`:auto-upload="false"`确保选择了文件之后不会立即开始上传;而`multiple`属性允许一次选择多个文件[^1]。 接着是在JavaScript/TypeScript脚本内编写相应的事件处理器以及自定义上传函数: ```javascript <script setup lang="ts"> import { ref } from &#39;vue&#39;; // 定义ref变量关联到DOM节点 const upload = ref(null); let fileList = ref([]); // 存储已选文件的信息 function handleChange(file, fileList) { console.log(&#39;File selected:&#39;, file.raw); } async function submitUpload() { const formData = new FormData(); // 将所有待上传文件加入FormData对象 fileList.value.forEach((item, index) => { formData.append(`files[${index}]`, item.raw); }); try { await fetch(&#39;/api/upload&#39;, { method: &#39;POST&#39;, body: formData, }); alert(&#39;Files uploaded successfully!&#39;); } catch (error) { console.error(error.message); } } </script> ``` 这段代码展示了如何收集用户所选文件并通过AJAX请求发送给服务器端进行保存。注意这里使用了`fetch()`来进行异步通信操作[^2]。 最后需要注意的是样式调整用户体验优化方面的工作,比如可以考虑增加进度条显示、错误提示框等内容以提高交互友好度[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值