npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

keke-alioss-upload-vue

v1.1.0

Published

一个基于 Vue 3 和阿里云 OSS 的高性能文件上传组件,支持断点续传、分片上传、多文件上传等功能。

Readme

keke-ali-oss-vue

一个基于 Vue 3 和阿里云 OSS 的高性能文件上传组件,支持断点续传、分片上传、多文件上传等功能。

✨ 特性

  • 🚀 断点续传:支持上传中断后继续上传,无需重新开始
  • 📦 分片上传:大文件自动分片上传,提高上传效率
  • 🔄 并发控制:支持多文件并发上传(默认最多 2 个文件同时上传)
  • 📊 进度追踪:实时显示上传进度
  • 🔐 STS Token 自动刷新:自动检测并刷新过期的临时凭证
  • 文件校验:支持上传前文件类型、大小等校验
  • 🎯 TypeScript 支持:完整的 TypeScript 类型定义
  • 🎨 灵活定制:支持自定义上传按钮和样式

📦 安装

npm install keke-ali-oss-vue
# 或
yarn add keke-ali-oss-vue
# 或
pnpm add keke-ali-oss-vue

🔧 依赖要求

  • Vue 3.0+
  • ali-oss 6.0+

🚀 快速开始

基础用法

<template>
  <OssUpload
    :getUploadToken="getUploadToken"
    @uploadFinish="handleUploadFinish"
  />
</template>

<script setup lang="ts">
import OssUpload from 'keke-ali-oss-vue';
import type { OssUploadParams } from 'keke-ali-oss-vue';

const getUploadToken = async (): Promise<OssUploadParams> => {
  // 调用后端接口获取 STS Token
  const response = await fetch('/api/getStsToken');
  const data = await response.json();
  
  return {
    options: {
      bucket: data.bucket,
      endpoint: data.endpoint,
      accessKeyId: data.accessKeyId,
      accessKeySecret: data.accessKeySecret,
      stsToken: data.securityToken,
    },
    ossUploadLimit: {
      filePath: data.ossObjectPath,
      defaultUrl: data.cdnProtocolDomainInfo,
      expiredDuration: data.expiredDuration, // 单位:秒
    },
  };
};

const handleUploadFinish = (taskList: any[], urls: string[], failedFiles: any[]) => {
  console.log('上传完成', urls);
};
</script>

通过 ref 调用上传

<template>
  <div>
    <button @click="ossUploadRef?.activeUpload()">点击上传</button>
    <span v-if="ossUploadRef?.loading">上传中...</span>
    <span>上传进度:{{ ossUploadRef?.uploadProgressVal }}%</span>
    
    <OssUpload
      ref="ossUploadRef"
      :getUploadToken="getUploadToken"
      @uploadFinish="handleUploadFinish"
    />
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import OssUpload from 'keke-ali-oss-vue';
import type { OssUploadParams } from 'keke-ali-oss-vue';

const ossUploadRef = ref('ossUploadRef');

const getUploadToken = async (): Promise<OssUploadParams> => {
  // ... 获取 token 的逻辑
};

const handleUploadFinish = (taskList: any[], urls: string[], failedFiles: any[]) => {
  console.log('上传完成', urls);
};
</script>

📖 API 文档

Props 参数

| 参数 | 说明 | 类型 | 必填 | 默认值 | |------|------|------|------|--------| | getUploadToken | 获取 STS Token 的函数 | () => Promise<OssUploadParams> | 是 | - | | multiple | 是否支持多选 | boolean | 否 | false | | limit | 限制上传数量(仅在 multipletrue 时生效) | number | 否 | undefined | | accept | 限制上传的文件类型,多个类型用逗号分隔,如:.jpg,.png,.pdf | string | 否 | '*' | | disabled | 是否禁用 | boolean | 否 | false | | beforeEachUpload | 单个文件上传前的校验钩子,返回 false 则不上传该文件 | (file: File) => Promise<boolean> | 否 | undefined | | beforeUpload | 批量上传前的校验钩子,返回 false 则不进行上传 | (files: File[]) => Promise<boolean> | 否 | undefined |

Events 事件

| 事件名 | 说明 | 回调参数 | |--------|------|----------| | uploadFinish | 所有文件上传完成时触发 | (taskList: TaskItem[], urls: string[], failedFiles: FailedFileMsg[]) | | exceed | 超出上传数量限制时触发 | (files: File[]) | | eachUploadFinish | 单个文件上传完成时触发 | (task: TaskItem, url: string) |

暴露的方法和属性

通过 ref 可以访问以下方法和属性:

| 方法/属性 | 说明 | 类型 | |-----------|------|------| | uploadFiles | 手动触发文件上传 | (files: File[]) => Promise<void> | | activeUpload | 激活文件选择对话框 | () => void | | uploadProgressVal | 上传进度百分比(0-100) | number | | loading | 是否正在上传 | boolean |

类型定义

interface OssUploadParams {
  options: {
    bucket: string;           // OSS Bucket 名称
    endpoint: string;         // OSS 地域域名
    accessKeyId: string;      // 临时访问密钥 ID
    accessKeySecret: string;  // 临时访问密钥 Secret
    stsToken: string;         // STS Token
  };
  ossUploadLimit: {
    filePath: string;         // OSS 文件路径前缀
    defaultUrl: string;       // CDN 访问域名
    expiredDuration: number;  // Token 过期时长(秒)
  };
}

interface TaskItem {
  uid: string;
  file: RcFile;
  fileName: string;
  fileType: string;
  fileSize: number;
  uploadStatus: 'waiting' | 'uploading' | 'fail' | 'success';
  ossUrl: string;
  progress: number;
  failReason?: '' | 'formatError';
  // ... 更多属性
}

interface FailedFileMsg {
  file: File;
  failReason?: string;
  status: string;
}

💡 使用示例

示例 1:限制文件类型和数量

<template>
  <OssUpload
    :getUploadToken="getUploadToken"
    :multiple="true"
    :limit="5"
    accept=".jpg,.jpeg,.png,.webp"
    @uploadFinish="handleUploadFinish"
    @exceed="handleExceed"
  />
</template>

<script setup lang="ts">
import OssUpload from 'keke-ali-oss-vue';
import type { OssUploadParams } from 'keke-ali-oss-vue';

const handleUploadFinish = (taskList: any[], urls: string[], failedFiles: any[]) => {
  if (failedFiles.length > 0) {
    console.warn('部分文件上传失败', failedFiles);
  }
  console.log('成功上传的文件 URL:', urls);
};

const handleExceed = (files: File[]) => {
  console.warn('超出上传数量限制', files);
  // 可以在这里显示提示信息
};
</script>

示例 2:上传前校验文件大小

<template>
  <OssUpload
    :getUploadToken="getUploadToken"
    :beforeEachUpload="validateFile"
    @uploadFinish="handleUploadFinish"
  />
</template>

<script setup lang="ts">
import OssUpload from 'keke-ali-oss-vue';

const validateFile = async (file: File): Promise<boolean> => {
  // 限制文件大小为 10MB
  const maxSize = 10 * 1024 * 1024;
  if (file.size > maxSize) {
    alert('文件大小不能超过 10MB');
    return false;
  }
  return true;
};
</script>

示例 3:批量上传前校验

<template>
  <OssUpload
    :getUploadToken="getUploadToken"
    :multiple="true"
    :beforeUpload="validateFiles"
    @uploadFinish="handleUploadFinish"
  />
</template>

<script setup lang="ts">
import OssUpload from 'keke-ali-oss-vue';

const validateFiles = async (files: File[]): Promise<boolean> => {
  // 检查总文件大小
  const totalSize = files.reduce((sum, file) => sum + file.size, 0);
  const maxTotalSize = 100 * 1024 * 1024; // 100MB
  
  if (totalSize > maxTotalSize) {
    alert('总文件大小不能超过 100MB');
    return false;
  }
  return true;
};
</script>

示例 4:监听单个文件上传完成

<template>
  <OssUpload
    :getUploadToken="getUploadToken"
    :multiple="true"
    @eachUploadFinish="handleEachUploadFinish"
    @uploadFinish="handleUploadFinish"
  />
</template>

<script setup lang="ts">
import OssUpload from 'keke-ali-oss-vue';

const handleEachUploadFinish = (task: any, url: string) => {
  console.log(`文件 ${task.fileName} 上传完成,URL: ${url}`);
  // 可以在这里更新 UI,显示每个文件的上传状态
};

const handleUploadFinish = (taskList: any[], urls: string[], failedFiles: any[]) => {
  console.log('所有文件上传完成');
};
</script>

示例 5:完整示例(包含进度显示)

<template>
  <div class="upload-container">
    <button 
      @click="ossUploadRef?.activeUpload()"
      :disabled="ossUploadRef?.loading"
    >
      {{ ossUploadRef?.loading ? '上传中...' : '选择文件' }}
    </button>
    
    <div v-if="ossUploadRef?.loading" class="progress">
      <div class="progress-bar" :style="{ width: `${ossUploadRef?.uploadProgressVal}%` }"></div>
      <span class="progress-text">{{ ossUploadRef?.uploadProgressVal }}%</span>
    </div>
    
    <div v-if="previewUrl" class="preview">
      <img :src="previewUrl" alt="预览图" />
    </div>
    
    <OssUpload
      ref="ossUploadRef"
      :getUploadToken="getUploadToken"
      accept=".jpg,.jpeg,.png,.webp"
      @uploadFinish="handleUploadFinish"
    />
  </div>
</template>

<script setup lang="ts">
import { ref, ref } from 'vue';
import OssUpload from 'keke-ali-oss-vue';
import type { OssUploadParams } from 'keke-ali-oss-vue';

const ossUploadRef = ref('ossUploadRef');
const previewUrl = ref('');

const getUploadToken = async (): Promise<OssUploadParams> => {
  // 从后端获取 STS Token
  const response = await fetch('/api/getStsToken');
  const data = await response.json();
  
  return {
    options: {
      bucket: data.bucket,
      endpoint: data.endpoint,
      accessKeyId: data.accessKeyId,
      accessKeySecret: data.accessKeySecret,
      stsToken: data.securityToken,
    },
    ossUploadLimit: {
      filePath: data.ossObjectPath,
      defaultUrl: data.cdnProtocolDomainInfo,
      expiredDuration: data.expiredDuration,
    },
  };
};

const handleUploadFinish = (taskList: any[], urls: string[], failedFiles: any[]) => {
  if (urls.length > 0) {
    previewUrl.value = urls[0];
  }
  if (failedFiles.length > 0) {
    console.error('上传失败的文件:', failedFiles);
  }
};
</script>

<style scoped>
.upload-container {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.progress {
  position: relative;
  width: 100%;
  height: 20px;
  background-color: #f0f0f0;
  border-radius: 4px;
  overflow: hidden;
}

.progress-bar {
  height: 100%;
  background-color: #409eff;
  transition: width 0.3s;
}

.progress-text {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 12px;
}

.preview img {
  max-width: 300px;
  height: auto;
}
</style>

⚙️ 配置说明

getUploadToken 返回值

getUploadToken 函数必须返回 OssUploadParams 类型的对象,包含以下字段:

  • options: OSS 客户端配置

    • bucket: OSS Bucket 名称
    • endpoint: OSS 地域域名(如:oss-cn-hangzhou.aliyuncs.com
    • accessKeyId: 临时访问密钥 ID
    • accessKeySecret: 临时访问密钥 Secret
    • stsToken: STS Token
  • ossUploadLimit: 上传限制配置

    • filePath: OSS 文件路径前缀(如:uploads/images/
    • defaultUrl: CDN 访问域名(如:https://cdn.example.com
    • expiredDuration: Token 过期时长(单位:秒)

📝 注意事项

  1. STS Token 获取getUploadToken 函数必须返回正确的 OssUploadParams 格式,包含完整的 OSS 配置信息。

  2. 文件类型限制accept 参数支持标准的 HTML input accept 格式,如 .jpg,.pngimage/*

  3. 并发上传:组件内部支持最大 2 个文件并发上传,每个文件使用 5 个分片并发上传。

  4. 断点续传:组件支持断点续传功能,上传失败后可以继续上传。

  5. Token 刷新:组件会自动检测 Token 是否过期(有效期不足 1 分钟时视为过期),并自动刷新。

  6. 文件命名:上传的文件会自动重命名为 {uid}_{timestamp}.{ext} 格式,避免文件名冲突。

  7. 分片大小:默认分片大小为 10MB,适合大多数场景。

🔍 常见问题

Q: 如何自定义上传按钮样式?
A: 组件本身只包含一个隐藏的 input 元素,你可以通过 ref 调用 activeUpload() 方法,然后自定义按钮样式。

Q: 如何获取上传进度?
A: 通过 ref 访问 uploadProgressVal 属性,它是一个 0-100 的数值,表示整体上传进度。

Q: 上传失败后如何重试?
A: 组件会在 uploadFinish 事件的 failedFiles 参数中返回失败的文件信息,你可以根据这些信息重新调用 uploadFiles 方法进行重试。

Q: 如何限制文件大小?
A: 使用 beforeEachUploadbeforeUpload 钩子函数进行文件大小校验,返回 false 即可阻止上传。

Q: 支持哪些文件类型?
A: 通过 accept 属性可以限制文件类型,支持所有标准的 MIME 类型和文件扩展名。

📄 类型导入

如果需要使用 TypeScript 类型,可以按以下方式导入:

import type { 
  TaskItem, 
  OssUploadParams, 
  RcFile,
  FailedFileMsg
} from 'keke-ali-oss-vue';

🤝 贡献

欢迎提交 Issue 和 Pull Request!

📜 许可证

MIT

🔗 相关链接