vue2的this指向问题

1、问题描述

async downloadTemplate() {  
      try {  
        let res = await planModel.getTemplate();  
        let url = res.url;  
        let name = '里程碑计划.xlsx';  
        this.downloadFile(url, name);  
      } catch (error) {  
        console.error('下载文件时发生错误:', error);  
      }  
    },  
    
    downloadFile(url, filename) {  
      // 获取文件流  
      let xhr = new XMLHttpRequest();  
      xhr.open('GET', url, true);  
      xhr.responseType = 'blob';  
  
      xhr.onload = function() {  
        if (this.status === 200) {  
          let blob = new Blob([this.response], {type: 'application/octet-stream'});  
          this.saveAs(blob, filename);  
        }  
      };  
  
      xhr.onerror = function() {  
        console.error('下载文件时网络错误');  
      };  
  
      xhr.send();  
    },  
    saveAs(blob, filename) {  
      if (window.navigator.msSaveOrOpenBlob) {  
        // IE 浏览器  
        navigator.msSaveBlob(blob, filename);  
      } else {  
        // 其他浏览器  
        let link = document.createElement('a');  
        link.href = window.URL.createObjectURL(blob);  
        link.download = filename;  
        link.style.display = 'none';  
        document.body.appendChild(link);  
        link.click();  
        document.body.removeChild(link);  
        window.URL.revokeObjectURL(link.href);  
      }  
    }  ,---plan-batch-milepost.vue:98  Uncaught TypeError: this.saveAs is not a function
    at xhr.onload (plan-batch-milepost.vue:98:16)

2、原因及解决措施

在您的代码中,this.saveAs 在 xhr.onload 回调函数中抛出 Uncaught TypeError: this.saveAs is not a function 错误,这是因为回调函数中的 this 上下文已经改变,不再指向 Vue 实例。要解决这个问题,您需要在回调函数外部保持对 Vue 实例的引用,然后在回调函数内部使用这个引用。

下面是修改后的代码,其中添加了一个 self 变量来保存 Vue 实例的引用:

 

javascript复制代码

export default {
methods: {
async downloadTemplate() {
try {
let res = await planModel.getTemplate();
let url = res.url;
let name = '里程碑计划.xlsx';
this.downloadFile(url, name);
} catch (error) {
console.error('下载文件时发生错误:', error);
}
},
downloadFile(url, filename) {
let self = this; // 保存当前 Vue 实例的引用
// 获取文件流
let xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'blob';
xhr.onload = function() {
if (this.status === 200) {
let blob = new Blob([this.response], {type: 'application/octet-stream'});
self.saveAs(blob, filename); // 使用 Vue 实例的引用来调用 saveAs 方法
}
};
xhr.onerror = function() {
console.error('下载文件时网络错误');
};
xhr.send();
},
saveAs(blob, filename) {
if (window.navigator.msSaveOrOpenBlob) {
// IE 浏览器
navigator.msSaveBlob(blob, filename);
} else {
// 其他浏览器
let link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = filename;
link.style.display = 'none';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
window.URL.revokeObjectURL(link.href);
}
}
}
}

在这个修改后的代码中,self 变量在 downloadFile 方法的开始处被赋值为 this,这样 self 就引用了 Vue 实例。然后,在 xhr.onload 回调函数中,我们使用 self.saveAs(blob, filename); 来调用 saveAs 方法,而不是 this.saveAs(blob, filename);。这样,不论回调函数如何改变 this 的上下文,self 始终指向 Vue 实例,因此能够正确地调用 saveAs 方法。

  • 10
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值