websanova / vue-upload

A simple, light weight and intuitive upload control for Vue.js.
MIT License
222 stars 34 forks source link

Nuxt Compatability #31

Open movepixels opened 6 years ago

movepixels commented 6 years ago

Is there a way to implement this into nuxt?

I was under the impression anything made for Vue can work in Nuxt if you know how to create the proper plugin. I created a simple vue-upload.js plugin like so:

import Vue from 'vue'
import VueUpload from '@websanova/vue-upload'

Vue.use(VueUpload)

Added the config to the nuxt.config.js and I get no errors until I attempt to upload a file.

Cannot read property 'post' of undefined

I tried various file sizes, some fail so its a sign its actually working. To the point where if the files is valid and the error for post comes about.

Looks to be this bit of code in upload.js causing the problem

function __http(data) {
        __upload.Vue
            .http
            .post(data.url, data.body, {progress: data.progress})
            .then(data.success, data.error);
    }

I assume because its using default Vue http post request where most nuxt and vue apps use axios and don't bother with vue-resource

Just curious. This component looks very promising and exactly what I need. Just my project is in Nuxt requiring SSR.

Thanks,

DAve

websanova commented 6 years ago

Hey Dave,

Yes, so ya, you can override the http method there as by default it's for vue-resource.

Just needs the axios or whatever version and should work then.

By the way if you are using axios and get it working would be great if you could share the code snippet and I can add it to the docs or maybe even just put it in the code directly of it's small enough.

movepixels commented 6 years ago

No problem. I plan to make it axios / nuxt friendly over the weekend and will share when finished. I'm no JS coder but I am sure I can figure it out.

I figure from what I did see it appears the http request is just in that one spot. Could be wrong but if thats the only one place it would save me from wondering.

Keep you posted.

Dave

websanova commented 6 years ago

Yes, it's just that one _http method which by default is the vue-resource http plugin.

Just need to override that one method with however axios does it.

KnutSv commented 5 years ago

Just thought I'd share in case it might help out others, this is a stripped down version of how i made it work in a component in an Nuxt application. In this case the application will return an error message as a Message attribute, but this might have to be changed depending on how your backend is set up:

<template lang="pug">
    div
        div
            button(v-bind:id="uiqueId" @click="$upload.select(uiqueId)" v-bind:disabled="$upload.meta(uiqueId).state === 'sending'") Drag and drop or press to upload
        div(v-if="$upload.files(uiqueId).progress.length")
            progress(max="100" v-bind:value="$upload.meta(uiqueId).percentComplete")
            div {{ $upload.meta(uiqueId).percentComplete }}% Complete
        div(v-if="!$upload.files(uiqueId).all.length") No uploads here yet.

        h2(v-if="$upload.files(uiqueId).progress.length") Progress
        div(v-for="file in $upload.files(uiqueId).progress")
            div {{ file.name }}
            progress(max="100" v-bind:value="file.percentComplete")
            div {{ file.percentComplete }}% Complete

        h2(v-if="$upload.files(uiqueId).queue.length") Queue
        div(v-for="file in $upload.files(uiqueId).queue")
            div {{ file.name }}
            div Queued for upload

        h2(v-if="$upload.files(uiqueId).success.length") Success
        div(v-for="file in $upload.files(uiqueId).success")
            div {{ file.name }}
            div Uploaded successfully.

        h2(v-if="$upload.files(uiqueId).error.length") Error
        div(v-for="file in $upload.files(uiqueId).error")
            div {{ file.name }}
            div {{ file.error[0].code }} {{ file.error[0].msg }}
</template>
<script>
import Vue from 'vue'
import VueUpload from '@websanova/vue-upload'

export default {
    name: 'file-upload',
    props: {
        uploadUrl: {
            type: String,
            required: true
        }
    },
    computed: {
        uiqueId() {
            return `file-upload-dropzone_${this._uid}`
        }
    },
    created() {
        Vue.use(VueUpload, {
            http: (data) => this.$axios.$post(data.url, data.body).then(data.success).catch(data.error),
            parseErrors: (error) => [{code: error.response.status, msg: (error.response.data != null && error.response.data.Message || error.response.statusText)}]
            }
        })
    },
    mounted() {
        this.$upload.on(this.uiqueId, {
            maxFilesSelect: 20,
            dropzoneId: this.uiqueId,
            multiple: true,
            url: this.uploadUrl,
            onStart() {},
            onSuccess(file, serverResponse) {},
            onError(error) {},
            onEnd() {}
        })
    },
    beforeDestroy() {
        this.$upload.off(this.uiqueId)
    }
}
</script>

Edit: Added server response to onSuccess callback function

movepixels commented 5 years ago

For Nuxt example: If the page is refreshed / F5 you get errors of undefined meta / files. Regualr navigation works but if you F5 the page with the upload component I get errors.