Index: src/UploadTest.vue
===================================================================
--- src/UploadTest.vue	(revision d45005e5b50b98b5f612846d824b31699c9366b4)
+++ src/UploadTest.vue	(revision 76e46d7f0a4df764d7c6f271bd194766229f4d19)
@@ -98,6 +98,4 @@
           <br />
           {{ progress.length }} / {{ current.length }} / {{ queue.length }}
-          <br />
-          <button @click='abort()'>abort</button>
           <b>errors:</b> <span v-for='error in errors'>{{ error.file.name }}</span>
           <b>progress:</b> <div v-for='item in progress'>{{ item }}</div>
Index: src/UploadZone.vue
===================================================================
--- src/UploadZone.vue	(revision d45005e5b50b98b5f612846d824b31699c9366b4)
+++ src/UploadZone.vue	(revision 76e46d7f0a4df764d7c6f271bd194766229f4d19)
@@ -3,5 +3,5 @@
 import { ref, computed, defineProps, withDefaults, defineEmits, getCurrentInstance, defineExpose, watch, nextTick } from 'vue'
 
-import $ from 'jQuery'
+import axios from 'axios'
 
 interface Props {
@@ -56,4 +56,6 @@
 }>()
 
+let abort_controller: any = null
+
 const do_emit = (code: string, ... args: any[]) => {
   // @ts-ignore
@@ -93,5 +95,5 @@
       for(const file of evt.dataTransfer.files)
         files.push(file)
-    else
+    else // XXX elem click
       for(const file of evt.target.files)
         files.push(file)
@@ -134,4 +136,10 @@
   if(state.value != State.s_wait)
     return
+
+  try {
+    abort_controller = new AbortController()
+  }
+  catch {
+  }
 
   do_emit('upload:start', [files])
@@ -205,27 +213,28 @@
   cur_file += 1
 
-  $.ajax({
+  const options = {
+    method: 'post',
     url: props.target,
-    type: 'POST',
     data: fd,
-    contentType: false,
-    processData: false,
-    xhr: (): any => {
-      const xhr = new window.XMLHttpRequest()
-
-      xhr.upload.addEventListener('progress', (evt): void => {
-        current.value.forEach((item) => {
-          if(item.file === cur) {
-            item.current = evt.loaded
-            item.total = evt.total
-          }
-        })
-        do_emit('upload:progress', progress.value, current.value, queue.value)
+    onUploadProgress: (evt: any) => {
+      if(aborted && abort_controller)
+        abort_controller.abort()
+
+      current.value.forEach((item) => {
+        if(item.file === cur) {
+          item.current = evt.loaded
+          item.total = evt.total
+        }
       })
 
-      return xhr
+      do_emit('upload:progress', progress.value, current.value, queue.value)
     }
-  })
-    .then((res: any) => {
+  } as any
+
+  if(abort_controller)
+    options.signal = abort_controller.signal
+
+  axios(options)
+    .then((res) => {
       current.value = current.value.filter((item) => {
         return item.file !== cur
@@ -234,6 +243,6 @@
       do_emit('upload:progress', progress.value, current.value, queue.value)
 
-      progress.value.push(res)
-      results.value.push(res)
+      progress.value.push(res.data)
+      results.value.push(res.data)
 
       cur_jobs -= 1
@@ -242,5 +251,5 @@
         if(props.autoReset || props.autoReset === '') {
           state.value = State.s_idle
-          files = []
+          files = [] // # XXX can drop w/o reset
           do_emit('files:clear', [])
         }
@@ -255,5 +264,5 @@
 
       if(cur_file == files.length && !cur_jobs) {
-        files = []
+        files = [] // XXX can drop w/o reset
         do_emit('files:clear', [])
 
@@ -279,5 +288,10 @@
         start_job()
     })
-    .catch((err: any) => {
+    .catch((err) => {
+      if(aborted && err.name == 'CanceledError') {
+        state.value = State.s_aborted
+        return err
+      }
+
       if(props.keepGoing || props.keepGoing === '') {
         current.value = current.value.filter((item) => {
@@ -286,9 +300,9 @@
 
         errors.value.push({
-          error: err,
+          error: err.response,
           file: cur
         })
 
-        do_emit('upload:error', err)
+        do_emit('upload:error', err.response)
 
         cur_jobs -= 1
@@ -305,6 +319,6 @@
       else {
         state.value = State.s_error
-        error.value = err
-        do_emit('upload:error', err)
+        error.value = err.response
+        do_emit('upload:error', err.response)
       }
     })
