代码之家  ›  专栏  ›  技术社区  ›  moses toh

如何在vue组件的加载函数中使return工作?

  •  0
  • moses toh  · 技术社区  · 7 年前

    我有如下vue组件:

    <template>
        <section>
            ...
        </section>
    </template>
    <script>
        export default {
            ...
            data() {
                return {
                    allowableTypes: ['jpg', 'jpeg', 'png'],
                    maximumSize: 4000000
                }
            },
            methods: {
                ...
                onFileChange(e) {
                    if (this.validate(e.target.files[0])) {
                        let files = e.target.files,
                            reader = new FileReader()
                        // if any values
                        if (files.length){
                            reader.onload = (e) => {
                                this.image = e.target.result
                            }
                            reader.readAsDataURL(files[0])
                        }
                    }
                },
                validate(image) {
                    // validation file type  
                    if (!this.allowableTypes.includes(image.name.split(".").pop().toLowerCase())) {
                        return false
                    }
                    // validation file size
                    if (image.size > this.maximumSize) {
                        return false
                    }
                    // validation image resolution
                    let img = new Image()
                    img.src = window.URL.createObjectURL(image)
                    let self = this
                    img.onload = function() {
                        let width = img.naturalWidth,
                            height = img.naturalHeight
    
                        window.URL.revokeObjectURL(img.src)
    
                        if(width != 850 && height != 350) {
                            return false
                        }
                    }
                    return true
                }
            }
        }
    </script>
    

    如果用户上传图像,它将调用 onFileChange 方法在显示图像之前,它将调用方法validate来验证图像。

    我试着验证文件大小和文件类型,这是可行的。这里的问题是验证解决方案。

    从我的代码来看,我的代码似乎是真的

    但当我这样尝试时:

    我上载图像时使用 width = 100 ,则, height = 100 ,如果它返回“false”。

    但当我运行代码时,它会返回 true

    似乎return在中不起作用 img.onload

    我如何解决这个问题?

    2 回复  |  直到 7 年前
        1
  •  2
  •   Guillaume Meral    7 年前

    处理异步验证的一种好方法是使用承诺:
    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

    如果您的目标是Internet Explorer,请确保使用以下多边形填充:
    https://github.com/stefanpenner/es6-promise
    您的代码如下所示:

    onFileChange(e) {
      let self = this
      this.validate(e.target.files[0])
        .then(function() {
          let files = e.target.files,
            reader = new FileReader()
          // if any values
          if (files.length) {
            reader.onload = (e) => {
              self.image = e.target.result
            }
            reader.readAsDataURL(files[0])
          }
        })
        .catch(function() {
          // do something in the case where the image is not valid
        })
    },
    validate(image) {
      let self = this
      return new Promise(function(resolve, reject) {
        // validation file type
        if (!self.allowableTypes.includes(image.name.split(".").pop().toLowerCase())) {
          reject()
        }
        // validation file size
        if (image.size > self.maximumSize) {
          reject()
        }
        // validation image resolution
        let img = new Image()
        img.src = window.URL.createObjectURL(image)
        img.onload = function() {
          let width = img.naturalWidth,
            height = img.naturalHeight
    
          window.URL.revokeObjectURL(img.src)
    
          if (width != 850 && height != 350) {
            reject()
          } else {
            resolve()
          }
        }
      })
    }
    

    如果您不想要或无法使用承诺,可以使用回调来实现相同的行为:

    onFileChange(e) {
      let self = this
      let validCallback = function() {
        let files = e.target.files,
          reader = new FileReader()
        // if any values
        if (files.length) {
          reader.onload = (e) => {
            self.image = e.target.result
          }
          reader.readAsDataURL(files[0])
        }
      }
      let unvalidCallback = function() {
        // do something in the case where the image is not valid
      }
      this.validate(e.target.files[0], validCallback, unvalidCallback)
    
    },
    validate(image, validCallback, unvalidCallback) {
      // validation file type
      if (!this.allowableTypes.includes(image.name.split(".").pop().toLowerCase())) {
        unvalidCallback()
        return
      }
      // validation file size
      if (image.size > this.maximumSize) {
        unvalidCallback()
        return
      }
      // validation image resolution
      let img = new Image()
      img.src = window.URL.createObjectURL(image)
      let self = this
      img.onload = function() {
        let width = img.naturalWidth,
          height = img.naturalHeight
    
        window.URL.revokeObjectURL(img.src)
    
        if (width != 850 && height != 350) {
          unvalidCallback()
          return
        } else {
          validCallback()
        }
      }
    }
    
        2
  •  0
  •   samayo    7 年前

    它是 onloadend onload

    将代码更改为:

    let self = this;     
    
    var reader = new FileReader(); 
    reader.onloadend = () => {
     // you logic here (use self, not this)
    }