Uncaught TypeError: this.testFunction is not a function

Uncaught TypeError: this.testFunction is not a function

我有一个带有上传组件的 Vue 应用程序,该组件获取图像 (dropzone),将其传递给 cropper (cropperjs) 并 returns 在裁剪后将其传递给 dropzone。 我想在上传之前压缩图像,所以我要从 dropzone 对象中获取图像并将其传递给压缩器 (compressorjs)。我正在为一个错误而苦苦挣扎,无法更进一步..情况就是这样:

裁剪方式:

cropImage() {
            // get image data for post processing, e.g. upload or setting image src
            this.$refs.cropper.getCroppedCanvas().toBlob((blob)=> {
                var croppedFile = this.blobToFile(blob, this.fileName)
                croppedFile.accepted = true
                this.$refs.myVueDropzone.dropzone.addFile(croppedFile)
                this.cropperReset()
            });
        },

此时我的 dropzone 获取裁剪后的图像并正确生成裁剪器缩略图。
现在我要启动上传方法,但在处理队列之前压缩图像。

launchUpload() {
            new Compressor(this.$refs.myVueDropzone.dropzone.files[0], {
                quality: 0.6,
                maxWidth: 250,
                minWidth: 250,
                success(compressedResult){
                    this.testFunction(compressedResult)
                },
                error(err) {
                    console.log(err.message);
                },
            })

            /*await this.$refs.myVueDropzone.processQueue()
            this.$refs.myVueDropzone.removeAllFiles()*/
        }

我要将文件传递给 Compressor,传递一些设置并获取图像的压缩版本“compressedResult”blob。我的问题是在其中使用 testFunction 会导致:

“未捕获的类型错误:this.testFunction 不是一个函数”

testFunction 只是一个虚拟函数,是我在尝试其他所有方法后创建的..

testFunction(compressed){
            this.$refs.myVueDropzone.removeAllFiles()
            this.$refs.myVueDropzone.addFile(compressed)
        },

console.log 进入 testFunction 结果“未定义”,似乎没有任何效果..
我在这里发布的每个方法都是 Vue 组件的“方法”对象的一部分。

组件交互的Vue部分:

<v-dialog
            v-model="is_show"
            persistent
            max-width="800px"
        >
            <v-card>
                <v-card-title>
                    <span class="text-h5">Upload File</span>
                </v-card-title>
                <v-card-text>
                    <vue-dropzone
                        ref="myVueDropzone"
                        id="dropzone"
                        :options="dropzoneOptions"
                        @vdropzone-file-added="(file) => passToCropper(file)"
                        @vdropzone-complete="reloadAndClose"
                    ></vue-dropzone>
                    <v-col cols="12" class="text-right">
                        <v-btn
                            @click="closeModal"
                            class="ma-2"
                            :disabled="loading"
                        >
                            Close
                        </v-btn>
                        <v-btn
                            @click="launchUpload"
                            class="ma-2"
                            color="primary"
                            :loading="loading"
                        >
                            Submit
                        </v-btn>
                    </v-col>
                </v-card-text>
            </v-card>
        </v-dialog>

如果我不压缩图像并在“addFile”部分进入 cropImage 方法之后处理我的 dropzone 队列,一切都会完美无缺。
非常感谢!!

您应该使用 arrow function expression 而不是函数表达式,因为使用函数表达式它会创建自己的 this 绑定。

所以在你的情况下 testFunction 在新的上下文中不存在(新的 this)。

success(compressedResult){
    this.testFunction(compressedResult)
 },

查看 this 如何在箭头函数表达式的情况下引用全局对象,以及 this 如何在函数表达式的情况下引用调用方法的对象:

const obj = {
  someProperty: 'someProperty',
  a: () => {
    console.log(this === window, this === obj)
  },
  b() {
    console.log(this === window, this === obj)
  }
}

obj.a()
obj.b()

您还可以保留函数表达式并使用 this 的存储引用,例如:

launchUpload() {
    const that = this;
    new Compressor(this.$refs.myVueDropzone.dropzone.files[0], {
        quality: 0.6,
        maxWidth: 250,
        minWidth: 250,
        success(compressedResult){
            that.testFunction(compressedResult)
        },
        error(err) {
            console.log(err.message);
        },
    })

    /*await this.$refs.myVueDropzone.processQueue()
    this.$refs.myVueDropzone.removeAllFiles()*/
}