为何无法在jsZip.loadAsync()中访问全局属性/方法?如何解决?
问题原因与解决方法
原因
你遇到的报错是因为普通函数回调改变了this的指向:在zip.loadAsync().then()的回调里用了普通function(zip),这个函数内部的this不再指向你的组件实例,而是指向该回调函数自身的执行上下文,所以找不到组件上的uploadBlob方法和messageService属性,才会抛出“Cannot read properties of undefined (reading 'uploadBlob')”的错误。
另外你提到的rootFile无法访问,是因为它是回调函数内部的局部变量,外部自然拿不到,不过这不是当前报错的核心问题。
解决方法
这里给你三种可行的修复方式,选一种习惯的用就行:
方法1:使用箭头函数(最简洁推荐)
箭头函数不会绑定自己的this,会继承外层作用域的this(也就是组件实例),直接把回调改成箭头函数即可:
scanfile(e) { var zip = new JSZip(); zip.loadAsync(e.target.files[0]).then((zip) => { // 改成箭头函数 let rootFile = []; for (let filename of Object.entries(zip.files)) { if (filename[0].match(/^[^/]+\.csv$/)) { rootFile.push(filename[0]); } } if (rootFile.length > 0) { this.uploadBlob(e); // 现在this能正确指向组件实例 } else { this.messageService.add({ severity: 'error', summary: 'Error', detail: 'Root level .csv file is missing ' }); } }).catch((e) => console.log(e)) }
方法2:提前保存组件的this到变量
在回调函数外部先把组件的this存到一个变量(比如that)里,回调里用这个变量代替this:
scanfile(e) { const that = this; // 提前保存组件的this var zip = new JSZip(); zip.loadAsync(e.target.files[0]).then(function (zip) { let rootFile = []; for (let filename of Object.entries(zip.files)) { if (filename[0].match(/^[^/]+\.csv$/)) { rootFile.push(filename[0]); } } if (rootFile.length > 0) { that.uploadBlob(e); // 用that代替this } else { that.messageService.add({ severity: 'error', summary: 'Error', detail: 'Root level .csv file is missing ' }); } }).catch((e) => console.log(e)) }
方法3:用bind()绑定this
给回调函数绑定组件的this,强制让回调里的this指向组件实例:
scanfile(e) { var zip = new JSZip(); zip.loadAsync(e.target.files[0]).then(function (zip) { let rootFile = []; for (let filename of Object.entries(zip.files)) { if (filename[0].match(/^[^/]+\.csv$/)) { rootFile.push(filename[0]); } } if (rootFile.length > 0) { this.uploadBlob(e); } else { this.messageService.add({ severity: 'error', summary: 'Error', detail: 'Root level .csv file is missing ' }); } }.bind(this)).catch((e) => console.log(e)) // 这里绑定this }
内容的提问来源于stack exchange,提问作者s d
相关产品推荐
相关产品推荐

