vue-chunk-uploader
v1.4.0
Published
Vue 3 chunked/resumable file uploader with selectable UI adapters (Quasar, Vuetify, Reka UI, Element Plus, Ant Design Vue, Naive UI, native)
Downloads
325
Maintainers
Readme
vue-chunk-uploader
A Vue 3 chunked file uploader compatible with the resumable.js protocol.
The upload core is UI-agnostic — you choose which adapter to use.
Choose a UI
| Import | UI | Required dependency |
|--------|----|---------------------|
| vue-chunk-uploader/quasar | Quasar | quasar |
| vue-chunk-uploader/vuetify | Vuetify 3 | vuetify |
| vue-chunk-uploader/reka | Reka UI | reka-ui |
| vue-chunk-uploader/element-plus | Element Plus | element-plus |
| vue-chunk-uploader/ant-design | Ant Design Vue | ant-design-vue |
| vue-chunk-uploader/naive | Naive UI | naive-ui |
| vue-chunk-uploader/native | Plain HTML | — |
| vue-chunk-uploader | Core only (no UI) | — |
Note about MUI: Material UI is for React. In the Vue ecosystem, the closest equivalent is Vuetify. For other UIs, use
native,reka, or theuseChunkUploadcomposable and build your own UI.
Install
npm install vue-chunk-uploader axios vueDepending on the UI:
# Quasar
npm install quasar
# or Vuetify
npm install vuetify
# or Reka UI
npm install reka-ui
# or Element Plus
npm install element-plus
# or Ant Design Vue
npm install ant-design-vue
# or Naive UI
npm install naive-uiUsage — Quasar
import { createApp } from 'vue'
import { Quasar } from 'quasar'
import VueChunkUploader from 'vue-chunk-uploader/quasar'
import axios from 'axios'
const api = axios.create({ baseURL: 'https://api.example.com', withCredentials: true })
const app = createApp(App)
app.use(Quasar)
app.use(VueChunkUploader, { httpClient: api })
app.mount('#app')<template>
<ChunkUploader
v-model="file"
url="/api/document/chunk/upload"
filled
bottom-slots
label="File"
@onSuccess="onSuccess"
@onError="onError"
/>
</template>
<script setup>
import { ref } from 'vue'
// or: import { ChunkUploader } from 'vue-chunk-uploader/quasar'
const file = ref(null)
</script>Usage — Vuetify
import VueChunkUploader from 'vue-chunk-uploader/vuetify'
app.use(VueChunkUploader, { httpClient: api })<template>
<ChunkUploader
v-model="file"
url="/api/document/chunk/upload"
label="File"
variant="outlined"
@onSuccess="onSuccess"
/>
</template>Usage — Element Plus
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import VueChunkUploader from 'vue-chunk-uploader/element-plus'
app.use(ElementPlus)
app.use(VueChunkUploader, { httpClient: api })<template>
<ChunkUploader
v-model="file"
url="/api/document/chunk/upload"
button-label="Select file"
accept=".pdf,.png"
@onSuccess="onSuccess"
/>
</template>
<script setup>
import { ref } from 'vue'
import { ChunkUploader } from 'vue-chunk-uploader/element-plus'
const file = ref(null)
</script>Usage — Ant Design Vue
import Antd from 'ant-design-vue'
import 'ant-design-vue/dist/reset.css'
import VueChunkUploader from 'vue-chunk-uploader/ant-design'
app.use(Antd)
app.use(VueChunkUploader, { httpClient: api })<template>
<ChunkUploader
v-model="file"
url="/api/document/chunk/upload"
button-label="Select file"
accept=".pdf,.png"
@onSuccess="onSuccess"
/>
</template>
<script setup>
import { ref } from 'vue'
import { ChunkUploader } from 'vue-chunk-uploader/ant-design'
const file = ref(null)
</script>Usage — Naive UI
import naive from 'naive-ui'
import VueChunkUploader from 'vue-chunk-uploader/naive'
app.use(naive)
app.use(VueChunkUploader, { httpClient: api })<template>
<ChunkUploader
v-model="file"
url="/api/document/chunk/upload"
button-label="Select file"
accept=".pdf,.png"
@onSuccess="onSuccess"
/>
</template>
<script setup>
import { ref } from 'vue'
import { ChunkUploader } from 'vue-chunk-uploader/naive'
const file = ref(null)
</script>Usage — Reka UI
Uses accessible Reka UI primitives (Label, Progress, Primitive). Since Reka is unstyled, import the package CSS (or override with your own styles).
import VueChunkUploader from 'vue-chunk-uploader/reka'
import 'vue-chunk-uploader/style.css'
app.use(VueChunkUploader, { httpClient: api })<template>
<ChunkUploader
v-model="file"
url="/api/document/chunk/upload"
label="File"
accept=".pdf,.png"
@onSuccess="onSuccess"
/>
</template>
<script setup>
import { ref } from 'vue'
import { ChunkUploader } from 'vue-chunk-uploader/reka'
import 'vue-chunk-uploader/style.css'
const file = ref(null)
</script>Usage — Native (no UI framework)
import VueChunkUploader from 'vue-chunk-uploader/native'
import 'vue-chunk-uploader/style.css'
app.use(VueChunkUploader, { httpClient: api })Or build a custom UI with the composable:
<script setup>
import { ref } from 'vue'
import { useChunkUpload } from 'vue-chunk-uploader'
const file = ref(null)
const props = {
modelValue: file,
url: '/api/upload',
autoUpload: true,
fields: {},
}
const emit = (event, payload) => {
if (event === 'update:modelValue') file.value = payload
}
const { progress, hasError, uploadFile, clear } = useChunkUpload(props, emit)
</script>Manual upload (autoUpload=false)
<template>
<ChunkUploader
ref="uploader"
v-model="file"
url="/api/document/chunk/upload"
:auto-upload="false"
/>
<button @click="submit">Upload</button>
</template>
<script setup>
import { ref } from 'vue'
const file = ref(null)
const uploader = ref(null)
async function submit() {
// Extra fields are sent only with the last chunk
await uploader.value.uploadFile({ document_id: 123 })
}
</script>Core only (no UI)
import { chunk, setDefaultHttpClient } from 'vue-chunk-uploader'
import axios from 'axios'
setDefaultHttpClient(axios.create({ baseURL: '/api' }))
await chunk(
'/document/chunk/upload',
file,
{ document_id: 1 },
(percent) => console.log(percent),
(err) => console.error(err),
(res) => console.log(res),
{ chunkSize: 1024 * 1024 },
)Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| modelValue / v-model | File | null | Selected file |
| url | string | — | Upload endpoint |
| autoUpload | boolean | true | Upload automatically after selection |
| fields | object | {} | Extra fields (sent with the last chunk) |
| httpClient | AxiosInstance | default / axios | HTTP client |
| chunkSize | number | 1MB | Chunk size |
| maxRequestsPerMinute | number | 80 | Client-side rate limit |
| rateLimitWindowMs | number | 60000 | Rate-limit window |
| label | string | '' | Label text (Reka adapter) |
| buttonLabel | string | 'Select file' | Button text (Element Plus / Ant Design / Naive UI adapters) |
UI-specific attrs are forwarded as well (e.g. q-file, v-file-input, el-upload, a-upload, n-upload, or native input[type=file] attrs).
Events
| Event | Payload |
|-------|---------|
| update:modelValue | File \| null |
| onSelectFile | uploader module |
| onProgress | percent: number |
| onError | error |
| onSuccess | response |
Exposed methods
| Method | Description |
|--------|-------------|
| uploadFile(extraFormData?) | Starts the upload; returns a Promise |
License
MIT
