Skip to content

上传 Upload

用户可传输文件或提交相应的内容。

基本使用

上传组件的基本用法。


代码事例
vue
<template>
  <fk-space direction="vertical" :style="{ width: '100%' }">
    <fk-upload action="/" />
    <fk-upload action="/" disabled style="margin-top: 40px;"/>
  </fk-space>
</template>

用户头像上传

点击上传用户头像,可使用 beforeUpload 限制用户上传的图片格式和大小。


代码事例
vue

<template>
  <fk-space direction="vertical" :style="{ width: '100%' }">
    <fk-upload
      action="/"
      :file-list="file ? [file] : []"
      :show-file-list="false"
      @change="onChange"
      @progress="onProgress"
    >
      <template #upload-button>
        <div
          :class="`fk-upload-list-item${
            file && file.status === 'error' ? ' fk-upload-list-item-error' : ''
          }`"
        >
          <div
            v-if="file && file.url"
            class="fk-upload-list-picture custom-upload-avatar"
          >
            <img :src="file.url" />
            <div class="fk-upload-list-picture-mask">
              <IconEdit />
            </div>
            <fk-progress
              v-if="file.status === 'uploading' && file.percent < 100"
              :percent="file.percent"
              type="circle"
              size="mini"
              :style="{
                position: 'absolute',
                left: '50%',
                top: '50%',
                transform: 'translateX(-50%) translateY(-50%)',
              }"
            />
          </div>
          <div v-else class="fk-upload-picture-card">
            <div class="fk-upload-picture-card-text">
              <IconPlus />
              <div style="margin-top: 10px; font-weight: 600">Upload</div>
            </div>
          </div>
        </div>
      </template>
    </fk-upload>
  </fk-space>
</template>

<script>
import { ref } from 'vue';
import { IconEdit, IconPlus } from '@erp/common';

export default {
  components: {IconPlus, IconEdit},
  setup() {
    const file = ref();

    const onChange = (_, currentFile) => {
      file.value = {
        ...currentFile,
        // url: URL.createObjectURL(currentFile.file),
      };
    };
    const onProgress = (currentFile) => {
      file.value = currentFile;
    };
    return {
      file,
      onChange,
      onProgress
    }
  },
};
</script>

已上传的文件列表

可以指定默认的已上传文件列表。


代码事例
vue
<template>
  <fk-upload action="/" showLink imagePreview :default-file-list="fileList" />
</template>

<script>
export default {
  setup() {
    const fileList = [
      {
        uid: '-1',
        name: 'ice.png',
        url: '//test.img.fukerp.com/default/AQZ2oYAqJgZf2DjwAAzF0LRCiosB6kvkG6f0eKSL.jpg',
      },
      {
        status: 'error',
        uid: '-2',
        percent: 0,
        response: '上传错误提示',
        name: 'cat.png',
        url: '//test.img.fukerp.com/default/j44G9LTLBxBkNlLu84HOSGF6qgzQLjg7kK3WuuVg.jpg',
      },
      {
        uid: '-3',
        name: 'light.png',
        url: '//test.img.fukerp.com/default/FLIrNHVfnvjvOXN40Rm1l5dugEwsjUDsxEDW3kIP.jpg',
      },
    ];

    return {
      fileList
    }
  },
};
</script>

照片墙

通过设置 list-type="picture-card" 开启照片墙模式。


代码事例
vue
<template>
  <fk-upload
    list-type="picture-card"
    action="/"
    :default-file-list="fileList"
    image-preview
  />
</template>

<script>
export default {
  setup() {
    const fileList = [
      {
        uid: '-2',
        name: '20200717-103937.png',
        url: '//test.img.fukerp.com/default/FLIrNHVfnvjvOXN40Rm1l5dugEwsjUDsxEDW3kIP.jpg',
      },
      {
        uid: '-1',
        name: 'hahhahahahaha.png',
        url: '//test.img.fukerp.com/default/j44G9LTLBxBkNlLu84HOSGF6qgzQLjg7kK3WuuVg.jpg',
      },
    ];

    return {
      fileList
    }
  },
};
</script>

拖拽上传

通过设置 draggable 开启对拖拽的支持。


代码事例
vue
<template>
  <fk-upload draggable action="/" />
</template>

图标列表样式

通过设置 list-type="picture" 开启图片列表样式


代码事例
vue
<template>
  <fk-space direction="vertical" style="width: 100%">
    <fk-upload
      list-type="picture"
      accept="*"
      action="/"
      image-preview
      :default-file-list="fileList"
    />
    <fk-upload
      draggable
      list-type="picture"
      accept="*"
      action="/"
      image-preview
      :default-file-list="fileList"
    />
  </fk-space>
</template>

<script>
export default {
  setup() {
    const fileList = [
      {
        uid: '-2',
        name: '20200717-103937.png',
        url: '//test.img.fukerp.com/default/FLIrNHVfnvjvOXN40Rm1l5dugEwsjUDsxEDW3kIP.jpg',
      },
      {
        uid: '-1',
        name: 'hahhahahahaha.png',
        url: '//test.img.fukerp.com/default/j44G9LTLBxBkNlLu84HOSGF6qgzQLjg7kK3WuuVg.jpg',
      },
    ];

    return {
      fileList
    }
  },
};
</script>

手动上传

设置 auto-uploadfalse 时候,可以通过调用 submit 方法进行手动上传。


代码事例
vue
<template>
  <div>
    <fk-upload
      ref="uploadRef"
      action="/"
      :auto-upload="false"
      multiple
      @change="onChange"
    >
      <template #upload-button>
        <fk-space>
          <fk-button> select file</fk-button>
          <fk-button type="primary" @click="submit"> start upload</fk-button>
          <fk-button type="primary" @click="submitOne">
            only upload one
          </fk-button>
        </fk-space>
      </template>
    </fk-upload>
  </div>
</template>

<script>
import { ref } from 'vue';

export default {
  setup() {
    const uploadRef = ref();
    const files = ref([]);

    const submitOne = (e) => {
      e.stopPropagation();
      console.log(files.value);
      uploadRef.value.submit(files.value.find((x) => x.status === 'init'));
    };

    const submit = (e) => {
      e.stopPropagation();
      uploadRef.value.submit();
    };

    const onChange = (fileList) => {
      files.value = fileList;
    };

    return {
      uploadRef,
      files,
      submitOne,
      submit,
      onChange,
    };
  },
};
</script>

上传前校验

beforeUpload 会在每一个文件上传之前执行。如果返回 false 或者 Promise.reject, 那么将会取消当前文件的上传。


代码事例
vue
<template>
  <fk-space direction="vertical" :style="{ width: '100%' }">
    <fk-upload action="/" @before-upload="beforeUpload" />
  </fk-space>
</template>

<script>
import { Modal } from '@erp/common';

export default {
  setup() {
    const beforeUpload = (file) => {
      return new Promise((resolve, reject) => {
        Modal.confirm({
          title: 'beforeUpload',
          content: `确认上传 ${file.name}`,
          onOk: () => resolve(true),
          onCancel: () => reject('cancel'),
        });
      });
    };
    return {
      beforeUpload
    }
  },
};
</script>

移除前校验

on-before-remove 会在每一个文件移除之前执行。如果返回 false 或者 Promise.reject, 那么将会取消当前文件的操作。


代码事例
vue
<template>
  <fk-space direction="vertical" :style="{ width: '100%' }">
    <fk-upload
      action="/"
      :default-file-list="[
        {
          uid: '-2',
          name: 'light.png',
          url: '//test.img.fukerp.com/default/FLIrNHVfnvjvOXN40Rm1l5dugEwsjUDsxEDW3kIP.jpg',
        },
        {
          uid: '-1',
          name: 'ice.png',
          url: '//test.img.fukerp.com/default/AQZ2oYAqJgZf2DjwAAzF0LRCiosB6kvkG6f0eKSL.jpg',
        },
      ]"
      @before-remove="beforeRemove"
    />
  </fk-space>
</template>

<script>
import { Modal } from '@erp/common';

export default {
  setup() {
    const beforeRemove = (file) => {
      return new Promise((resolve, reject) => {
        Modal.confirm({
          title: 'on-before-remove',
          content: `确认删除 ${file.name}`,
          onOk: () => resolve(true),
          onCancel: () => reject('cancel'),
        });
      });
    };

    return {
      beforeRemove
    }
  },
};
</script>

限制上传数量

通过 limit 限制上传的最大数量。超出后上传按钮会隐藏.


代码事例
vue
<template>
  <fk-upload multiple action="/" :limit="3" />
</template>

自定义上传节点

可以通过插槽 upload-button 传入自定义内容作为文件上传的触发节点。


代码事例
vue
<template>
  <fk-upload action="/">
    <template #upload-button>
      <div
        style="
        background-color: var(--color-fill-2);
        color: var(--color-text-1);
        border: 1px dashed var(--color-fill-4);
        height: 158px;
        width: 380px;
        border-radius: 2;
        line-height: 158px;
        text-align: center;"
      >
        <div>
          Drag the file here or
          <span style="color: #3370FF"> Click to upload</span>
        </div>
      </div>
    </template>
  </fk-upload>
</template>

自定义图标

自定义图标


代码事例
vue

<template>
  <div>
    <div style="margin-bottom: 20px;">
      <fk-space>
        <span>Type: </span>
        <fk-radio-group v-model="type">
          <fk-radio value="text">text</fk-radio>
          <fk-radio value="picture">picture</fk-radio>
          <fk-radio value="picture-card">picture-card</fk-radio>
        </fk-radio-group>
      </fk-space>
    </div>
    <fk-upload
      action="/"
      :list-type="type"
      :default-file-list="[
        {
          uid: '-1',
          name: 'ice.png',
          url: '//test.img.fukerp.com/default/AQZ2oYAqJgZf2DjwAAzF0LRCiosB6kvkG6f0eKSL.jpg',
        },
        {
          uid: '-3',
          name: 'light.png',
          url: '//test.img.fukerp.com/default/FLIrNHVfnvjvOXN40Rm1l5dugEwsjUDsxEDW3kIP.jpg',
        },
      ]"
      :custom-icon="getCustomIcon()"
    />
  </div>
</template>

<script>
import { h, ref } from 'vue';
import { IconClose, IconFaceFrownFill, IconFileAudio, IconUpload } from '@erp/common';

export default {
  setup() {
    const type = ref('text');
    const getCustomIcon = () => {
      return {
        retryIcon: () => h(IconUpload),
        cancelIcon: () => h(IconClose),
        fileIcon: () => h(IconFileAudio),
        removeIcon: () => h(IconClose),
        errorIcon: () => h(IconFaceFrownFill),
        fileName: (file) => {
          return `文件名: ${file.name}`
        },
      };
    };

    return {
      type,
      getCustomIcon
    }
  },
};
</script>

自定义上传请求

可以通过 custom-request 实现自定义上传请求。


代码事例
vue
<template>
  <fk-upload :custom-request="customRequest" />
</template>

<script>
export default {
  setup() {
    const customRequest = (option) => {
      const {onProgress, onError, onSuccess, fileItem, name} = option
      const xhr = new XMLHttpRequest();
      if (xhr.upload) {
        xhr.upload.onprogress = function (event) {
          let percent;
          if (event.total > 0) {
            // 0 ~ 1
            percent = event.loaded / event.total;
          }
          onProgress(percent, event);
        };
      }
      xhr.onerror = function error(e) {
        onError(e);
      };
      xhr.onload = function onload() {
        if (xhr.status < 200 || xhr.status >= 300) {
          return onError(xhr.responseText);
        }
        onSuccess(xhr.response);
      };

      const formData = new FormData();
      formData.append(name || 'file', fileItem.file);
      xhr.open('post', '//upload-z2.qbox.me/', true);
      xhr.send(formData);

      return {
        abort() {
          xhr.abort()
        }
      }
    };

    return {
      customRequest
    }
  },
}
</script>

文件夹上传

可以通过 directory 开启文件夹上传


代码事例
vue
<template>
  <fk-space direction="vertical" :style="{ width: '100%' }">
    <fk-upload action="/" directory />
  </fk-space>
</template>

API

<upload> Props

参数名描述类型默认值版本
file-list (v-model)文件列表FileItem[]-
default-file-list默认的文件列表(非受控状态)FileItem[][]
accept接收的上传文件类型,具体参考 HTML标准string-
action上传的URLstring-
disabled是否禁用booleanfalse
multiple是否支持多文件上传booleanfalse
directory是否支持文件夹上传(需要浏览器支持)booleanfalse
draggable是否支持拖拽上传booleanfalse
drag-text拖拽提示文字string-
tip提示文字string-
tooltipHover 提示文字string-
headers上传请求附加的头信息Record<string, string>-
data上传请求附加的数据Record<string, string | Blob> | ((fileItem: FileItem) => Record<string, string | Blob>)-
name上传的文件名string | ((fileItem: FileItem) => string)-
with-credentials上传请求是否携带 cookiebooleanfalse
custom-request自定义上传行为(option: RequestOption) => UploadRequest-
limit限制上传文件的数量。0表示不限制number0
auto-upload是否自动上传文件booleantrue
show-file-list是否显示文件列表booleantrue
show-remove-button是否显示删除按钮booleantrue1.0.0
show-retry-button是否显示重试按钮booleantrue1.0.0
show-cancel-button是否显示取消按钮booleantrue1.0.0
show-upload-button是否显示上传按钮。boolean | { showOnExceedLimit: boolean }true1.0.0
show-preview-button照片墙是否显示预览按钮booleantrue1.0.0
show-picture-name是否显示图片名称booleantrue
download是否在 <a> 链接上添加 download 属性booleanfalse1.0.0
show-link在列表模式下,如果上传的文件存在 URL 则展示链接。如果关闭仅展示文字并且点击可以触发 preview 事件。booleantrue1.0.0
image-loading<img> 的原生 HTML 属性,需要浏览器支持'eager' | 'lazy'-1.0.0
list-type图片列表类型'text' | 'picture' | 'picture-card''text'
response-url-keyResponse中获取图片URL的key,开启后会用上传的图片替换预加载的图片string | ((fileItem: FileItem) => string)-
custom-icon自定义图标CustomIcon-
image-preview是否使用 ImagePreview 组件进行预览booleanfalse1.0.0
on-before-upload上传文件前触发(file: File) => boolean | Promise<boolean | File>-
on-after-upload上传文件后触发(file: FileItem) => void-
on-before-remove移除文件前触发(fileItem: FileItem) => Promise<boolean>-
on-button-click点击上传按钮触发(如果返回 Promise 则会关闭默认 input 上传)(event: Event) => Promise<FileList> | void-
button-text上传按钮上展示的文字string-
pasted是否支持复制粘贴booleantrue

<upload> Events

事件名描述参数
exceed-limit上传的文件超出限制后触发fileList: FileItem[]
files: File[]
change上传的文件状态发生改变时触发fileList: FileItem[]
fileItem: fileItem
progress上传中的文件进度改变时触发fileItem: fileItem
ev: ProgressEvent
preview点击图片预览时的触发fileItem: FileItem
success上传成功时触发fileItem: FileItem
error上传失败时触发fileItem: FileItem

<upload> Methods

方法名描述参数返回值版本
submit上传文件(已经初始化完成的文件)fileItem: FileItem-
abort中止上传fileItem: FileItem-
updateFile更新文件id: string
file: File
-
upload上传文件files: File[]-1.0.0

<upload> Slots

插槽名描述参数版本
extra-button上传列表额外按钮fileItem: FileItem1.0.0
image自定义图片fileItem: FileItem1.0.0
file-name文件名称-1.0.0
file-icon文件图标-1.0.0
remove-icon删除图标-1.0.0
preview-icon预览图标-1.0.0
cancel-icon取消图标-1.0.0
start-icon开始图标-1.0.0
error-icon失败图标-1.0.0
success-icon成功图标-1.0.0
retry-icon重试图标-1.0.0
upload-button上传按钮-
upload-item上传列表的项目fileItem: FileItem
index: number

FileItem

参数名描述类型默认值
uid当前上传文件的唯一标示string-
status当前上传文件的状态FileStatus-
file文件对象File-
percent上传进度百分比number-
response当前文件上传请求返回的响应any-
url文件地址string-
name文件名string-
id文件idstring-

CustomIcon

参数名描述类型默认值
startIcon开始图标RenderFunction-
cancelIcon取消图标RenderFunction-
retryIcon重试图标RenderFunction-
successIcon成功图标RenderFunction-
errorIcon失败图标RenderFunction-
removeIcon移除图标RenderFunction-
previewIcon预览图标RenderFunction-
fileIcon文件图标(fileItem: FileItem) => VNode-
fileName文件名(fileItem: FileItem) => string | VNode-

RequestOption

参数名描述类型默认值
action上传的URLstring-
headers请求报文的头信息Record<string, string>-
name上传文件的文件名string | ((fileItem: FileItem) => string)-
fileItem上传文件FileItem-
data附加的请求信息Record<string, string | Blob> | ((fileItem: FileItem) => Record<string, string | Blob>)-
withCredentials是否携带cookie信息booleanfalse
onProgress更新当前文件的上传进度。percent: 当前上传进度百分比(percent: number, event?: ProgressEvent) => void-
onSuccess上传成功后,调用onSuccess方法,传入的response参数将会附加到当前上传文件的response字段上(response?: any) => void-
onError上传失败后,调用onError方法,传入的response参数将会附加到当前上传文件的response字段上(response?: any) => void-
async请求booleanfalse

UploadRequest

参数名描述类型默认值
abort终止上传() => void-

基于 MIT 许可发布