细品文件上传—el-upload

细品文件上传—el-upload

el-upload

老规矩,我们先放一段官方代码方便说明

<template>
  <el-upload
    v-model:file-list="fileList"
    class="upload-demo"
    action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
    multiple
    :on-preview="handlePreview"
    :on-remove="handleRemove"
    :before-remove="beforeRemove"
    :limit="3"
    :on-exceed="handleExceed"
  >
    <el-button type="primary">Click to upload</el-button>
    <template #tip>
      <div class="el-upload__tip">
        jpg/png files with a size less than 500KB.
      </div>
    </template>
  </el-upload>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'

import type { UploadProps, UploadUserFile } from 'element-plus'

const fileList = ref<UploadUserFile[]>([
  {
    name: 'element-plus-logo.svg',
    url: 'https://element-plus.org/images/element-plus-logo.svg',
  },
  {
    name: 'element-plus-logo2.svg',
    url: 'https://element-plus.org/images/element-plus-logo.svg',
  },
])

const handleRemove: UploadProps['onRemove'] = (file, uploadFiles) => {
  console.log(file, uploadFiles)
}

const handlePreview: UploadProps['onPreview'] = (uploadFile) => {
  console.log(uploadFile)
}

const handleExceed: UploadProps['onExceed'] = (files, uploadFiles) => {
  ElMessage.warning(
    `The limit is 3, you selected ${files.length} files this time, add up to ${
      files.length + uploadFiles.length
    } totally`
  )
}

const beforeRemove: UploadProps['beforeRemove'] = (uploadFile, uploadFiles) => {
  return ElMessageBox.confirm(
    `Cancel the transfer of ${uploadFile.name} ?`
  ).then(
    () => true,
    () => false
  )
}
</script>

大家应该都挺好奇导入进来的两个类型里都有些什么吧:

// UploadProps包含了Upload组件所有的属性类型
type UploadProps = {
action: string // 上传的地址
headers?: Headers | Record<string, any> // 设置上传的请求头部
method?: string // 上传请求方法,默认post
multiple?: boolean // 是否支持多选文件
data?: Record<string, any> // 上传时附带的额外参数
name?: string // 上传的文件字段名,默认file
withCredentials?: boolean // 支持发送cookie凭证信息
showFileList?: boolean // 是否显示已上传文件列表
drag?: boolean // 是否启用拖拽上传
accept?: string // 接受上传的文件类型
fileList?: UploadUserFile[] // 上传的文件列表
listType?: ‘text’ | ‘picture’ | ‘picture-card’ // 文件列表的类型
autoUpload?: boolean // 是否自动上传
disabled?: boolean // 是否禁用
limit?: number // 最大允许上传个数
}

// UploadUserFile定义了上传文件的数据结构
interface UploadUserFile {
name: string // 文件名
url?: string // 文件URL地址
uid: number | string // 文件唯一标识
status?: ‘ready’ | ‘uploading’ | ‘success’ | ‘fail’ // 文件状态
size?: number // 文件大小
raw?: File // 原始文件对象
response?: any // 服务器响应内容
percentage?: number // 上传进度
}

当然还有一些钩子函数,结果就是这些东西和官方文档里给出的api基本一致,我就不过多关注了。

const handleRemove: UploadProps['onRemove'] = (file, uploadFiles) => {
  console.log(file, uploadFiles)
}

但是这一段代码风格非常奇怪,结果就是我才疏学浅了没看懂:首先UploadProps[‘onRemove’]这是 TypeScript 中的索引访问类型(Indexed Access Types)语法,用于获取一个类型中特定属性的类型。也就是说interface里的属性可以是一个方法,这里就是用这种方式拿到这个方法的类型。实际上就是将handleRemove作为一个方法,就是一个箭头函数。至于 (file, uploadFiles),则是upload组件自动传入的,file是选中的文件,uploadFiles则是所有文件。

好了这下全部都明了了。我们再来看要怎么做文件上传:

其实也非常简单,通过el-upload包裹,在里面放入一个不带@click的按钮,点击它会触发el-upload的默认方法,选择文件(通过一个隐藏的input),这时会按顺序触发钩子(上传前,文件状态改变时,文件上传时,上传成功,上传失败,超出限制时)

需要注意的是它默认带了axios的方法,比如action作为它的默认项和必须项,以及默认了post方法等。如果你想要全部自己来,你可以让action=’#’,然后在各个钩子的地方自己写。

拖拽上传的实现通过监听拖拽事件完成,点击上传则是会整个区域被点击都会触发隐藏的input。

还有一种手动上传,将auto-upload设为false,再后续改变uploadRef.value!.submit()。

不好意思,写的比较混乱,主要还是边学边记导致的。总结就是如果要用upload上传还是很简单的,只要包裹一个按钮就可以触发文件上传,填写action就可以将文件传到需要的url。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值