Vue Js - 文件输入更改后发送axios请求

Posted

技术标签:

【中文标题】Vue Js - 文件输入更改后发送axios请求【英文标题】:Vue Js - Sending axios request after file input changes 【发布时间】:2019-01-29 19:23:35 【问题描述】:

编辑

This answer 确实解决了背靠背运行两个不同功能的问题。不过,我的问题专门涉及文件处理输入的行为以及链接第二个事件的时刻(由@Igor 的答案中的第二个示例解决)。

问题

我有一个文件上传 Vue 组件,它工作得非常好。我想做的改进是让它在“单击”时工作,这意味着应该触发upload() 方法以响应createImage() 完成。我该怎么做?

<template>
<div>
    <div>
        <label>Image:</label>
        <img :src="(image) ? image : tempImage" class="img-fluid">
        <div class="custom-file">
            <input type="file" v-on:change="onFileChange" class="custom-file-input"
            :class=" 'border-0':image ">
            <label class="custom-file-label" for="customFile">
                 filename ? filename : 'Choose pic' 
            </label>
        </div>
    </div>
    <div>
        <button class="btn btn-success btn-block" 
        :disabled="!image"
        @click.prevent="upload">
            Upload
        </button>
    </div>
</div>
</template>
<script>
    export default
        props: ['tempImage'],
        data()
            return 
                image: '',
                filename: ''
            
        ,
        methods: 
            onFileChange(e) 
                let files = e.target.files || e.dataTransfer.files;
                this.$parent.uploading = true;
                if (!files.length)
                    return;
                this.createImage(files[0]);
            ,
            createImage(file) 
                let reader = new FileReader();
                let vm = this;
                reader.onload = (e) => 
                    vm.image = e.target.result;
                ;
                reader.readAsDataURL(file);
                vm.filename = file.name;
            ,
            upload()
                console.log(this.image);
                axios.post('/api/upload',image: this.image).then(res => 
                    if( !res.data.errors )
                       this.$parent.tempData.image = res.data.src;
                       this.$parent.uploading = false;
                     else 
                        console.log(res.data.errors);
                    
                );
            
        
    
</script>

【问题讨论】:

Run function after another one completes的可能重复 【参考方案1】:

createImage() 调用upload() 怎么样?

createImage(file) 
  let reader = new FileReader();
  let vm = this;
  reader.onload = (e) => 
    vm.image = e.target.result;
    vm.filename = file.name;
    this.upload();
  ;
  reader.readAsDataURL(file);

或将upload() 作为回调传递:

onFileChange(e) 
  let files = e.target.files || e.dataTransfer.files;
  this.$parent.uploading = true;
  if (!files.length)
    return;
  this.createImage(files[0], this.upload);
,
createImage(file, callback) 
  let reader = new FileReader();
  let vm = this;
  reader.onload = (e) => 
    vm.image = e.target.result;
    vm.filename = file.name;
    if (callback) callback();
  ;
  reader.readAsDataURL(file);

Fiddle

【讨论】:

我已经尝试过您的第一种方法但没有成功,因为在调用 upload()image 为空(这就是记录 image 的原因)。试了第二个,结果一样。【参考方案2】:

您首先创建一个变量 isUploading,初始值为false。然后在你的方法upload中你首先检查如果isUploading变量是假的,如果是假的,开始上传,否则,要么什么都不做,要么通知用户页面仍在上传图片。

代码可能如下所示:

var isUploading = false;
export default 
  // ...
  upload() 
    // If not uploading anything start the upload
    if (!isUploading) 
      isUploading = true;
      console.log(this.image);
      axios.post('/api/upload', 
        image: this.image
      ).then(res => 
        if (!res.data.errors) 
          this.$parent.tempData.image = res.data.src;
          this.$parent.uploading = false;
         else 
          console.log(res.data.errors);
        
      );
     else 
      // Do other stuff here
    
  
  // ...

【讨论】:

以上是关于Vue Js - 文件输入更改后发送axios请求的主要内容,如果未能解决你的问题,请参考以下文章

成功调用 axios 后,Vue.js 组件不会发送到父级

axios请求后的VUE JS动态背景图片

Vue 使用axios发送请求

vue js中的axios将请求作为字符串而不是对象发送

在 Vue.js 中使用 axios 向 Laravel API 发送获取请求

vue中axios怎么分服务