0
votes

Envoi de photo avec vuejs

J'utilise ElementUi uploader et je dois envoyer mon fichier avec le reste de mes données de formulaire, mais il ne semble pas envoyer les bons détails de la photo au back-end:

Captures d'écran

Journal de la console lorsque je sélectionne une image code >

 one

Données envoyées au back-end

 deux

Code

entrée de photo

export default {
    data() {
        return {
            dialogImageUrl: '',
            dialogVisible: false,
            form: {
                name: '',
                slug: '',
                price: '',
                new_price: '',
                sku: '',
                qty: 1,
                active: '',
                photo: '',
                shortDesc: '',
                longDesc: '',
                region: '',
                date1: '',
                date2: '',
                type: [],
                tags: [],
                brand_id: '',
                categories: [],
                resource: '',
                user_id: ''
            }
        }
    },
    methods: {
        onSubmit(e) { //send data to back-end
            e.preventDefault();
            axios.post('/api/admin/products/store', this.form)
            .then(res => {
                console.log(res);
            })
            .catch(error => {
                console.log(error);
            })
        },
        handleRemove(file) {
            this.form.photo = ''; // remove photo from from when it's removed
        },
        photoChanged(file, fileList){
            this.form.photo = file.raw;  // add photo to form when it's selected
            console.log('file', file) // screenshot 1
            console.log('raw', file.raw) //screenshot 2
        },
        handlePictureCardPreview(file) {
            this.dialogImageUrl = file.url;
            this.dialogVisible = true;
        },
        handleExceed(files, fileList) {
            this.$message.warning(`The limit is 1, you selected ${files.length} files this time, add up to ${files.length + fileList.length} totally, remove old image and try again.`);
        },
        beforeRemove(file) {
            return this.$confirm(`Cancel the transfert of ${ file.name } ?`);
        }
    },
  }
</script>

Script code >

<el-upload
    action="#"
    :limit="1"
    :multiple="false"
    :on-change="photoChanged"
    :on-exceed="handleExceed"
    list-type="picture-card"
    :on-remove="handleRemove"
    :on-preview="handlePictureCardPreview"
    :before-remove="beforeRemove"
    :auto-upload="false">
    <i slot="default" class="el-icon-plus"></i>
</el-upload>
<el-dialog :visible.sync="dialogVisible">
    <img width="100%" :src="dialogImageUrl" alt="">
</el-dialog>

Une idée?


2 commentaires

convertissez votre fichier en base64 alors c'est tout.


@ Qonvex620 comment faire cela?


3 Réponses :


0
votes

convertissez votre fichier en base64

lorsque vous sélectionnez une image, utilisez le code ci-dessous

       onImageChange() {
          let file = this.form.photo

          if (file == '')
                return;

           this.createImage(file);
       }

       createImage(file) {
           let reader = new FileReader();
           let el = this
           reader.onload = (e) => {
                el.form.photo = e.target.files[0];      
           };
           reader.readAsDataURL(file);
       },

attachez la fonction onImageChange dans votre fichier d'entrée


13 commentaires

lorsque je sélectionne un fichier, il renvoie Erreur dans le gestionnaire v-on: "TypeError: Impossible d'exécuter 'readAsDataURL' sur 'FileReader': le paramètre 1 n'est pas de type 'Blob'."


Erreur dans le gestionnaire v-on: "TypeError: Impossible d'exécuter 'readAsDataURL' sur 'FileReader': le paramètre 1 n'est pas de type 'Blob'."


comment passez-vous le fichier dans la fonction onImageChange?, peut-être que vous ne passez pas un fichier


fondamentalement, je n'utilise que votre fonction createImage et change le nom en photoChanged car ma photoChanged est sur la méthode de changement : on-change = " photoChanged " donc le fichier existe définitivement, mais certains comment nous ne pouvons pas le lire avec fileReader ()


photoChanged (fichier) {let reader = new FileReader (); reader.onload = (e) => {this.form.photo = e.target.files [0]; }; reader.readAsDataURL (fichier); },


dans votre fichier d'entrée, comment le joindre? Je suppose que vous avez utilisé v-model dessus et que vous l'utilisez comme une amende sur cette fonction


OK il n'y avait pas de v-model = "form.photo" j'en ajoute un mais le résultat est le même


ok maintenant ne renvoie pas d'erreur mais envoie la photo vide à la photo back-end: ""


envoie toujours vide: /


J'ai essayé ce reader.onload = (e) => {console.log ('e', e) mais rien ne s'imprime dans la console. certains comment le processus n'atteindra pas ce point


pouvez-vous afficher le journal de la console de this.form.photo sur onChange?


avec ce photoChanged (ee) {console.log (ee) let file = this.form.photo if (file == '') return; this.createImage (fichier); console.log (this.form.photo)}, j'obtiens ee dans la console qui est identique à ma première capture d'écran, mais rien ne s'imprime à propos de form.photo peut-être que l'instruction if fait quelque chose de mal \


supprimez d'abord la condition pour vérifier quelle est la valeur de votre formulaire.



1
votes

J'ai utilisé FormData pour envoyer la photo ou le document au serveur. JavaScript FormData

  <form id="myForm" name="myForm">
    <div>
        <label for="username">Enter name:</label>
        <input type="text" id="username" name="username" v-model="imageData.name">
      </div>
     <div>
        <label for="useracc">Enter account number:</label>
        <input type="text" id="useracc" name="useracc" v-model="imageData.account">
      </div>
    <label for="userfile">Upload file:</label>
    <input type="file" id="userfile" name="userfile">
  </div>
  <input type="submit" value="Submit!">
</form>

export default {
    data() {
        return { 
            imageData: {}
        }
    },
    methods: {
        uploadImageToServer() {
            // 1.Save the form Data and return the new id to save the image 
            axios.post('/api/admin/products/store', this.imageData)
            .then(res => {
                if(res.id) {
                //2. Save the image to id
                let formData = new FormData();
                let file = document.getElementById('userfile');
                formData.append('file', file)
                axios.post('/api/admin/products/image/{id}', formData)
                    .then(res => {
                        console.log(res)
                    })
                }
            })
            .catch(err => {
                console.log(err)
            }) 

        }
    }
}

Ici, Les données de formulaire et les données de fichier ne peuvent pas être envoyées en une seule demande. 1. Sauvegardez les données du formulaire et renvoyez l'identifiant. 2. Sauvegarde des données d'image dans l'ID. Remplacez le code HTML par la syntaxe 'element-ui'. Assurez-vous que votre API de repos reçoit les données du formulaire en entrée.


1 commentaires

oui mais le problème avec ceci est la façon dont la balise el-upload> traite les données d'image sinon ce ne serait pas le problème et formData fonctionnerait très bien.



0
votes

Résolu

Eh bien, j'ai décidé de renoncer à envoyer une image avec le reste des données au backend et de télécharger d'abord l'image avec action = "#" dans mon entrée et en retour, j'obtiens le nom du fichier dans mon formulaire et envoyez simplement le nom du fichier avec le reste du formulaire au lieu d'envoyer le fichier image.

<el-upload
  action="/api/upload"
  :on-success="handleAvatarSuccess"
.....>


methods: {
  handleAvatarSuccess(res, file) {
    this.form.photo = res.data;
  },
}

Donc, il envoie mon fichier au back-end dès qu'il est sélectionné et défini le nom du fichier stocké dans mon form.photo et ce nom sera envoyé avec le reste de mes entrées de formulaire.

J'espère que cela pourrait également être utile à d'autres. p >


0 commentaires