Vue方法嵌套函数中访问this.data对象的问题与解决办法
Vue嵌套函数内修改data对象的this作用域问题解决方案
在Vue开发中,需要在文件上传回调的多层嵌套函数内更新组件data数据时,常遇到this指向不符合预期的问题,常规直接访问this、调用vm实例副本、vm.$root等方案均无法生效。
错误代码示例
// 该方法绑定在上传组件的 :on-change="handlePreview" 事件上 handlePreview(file,files) { var reader = new FileReader(); reader.onload = function (reader) { papaparse.parse(reader.target.result, { step: function(row) { console.log("Row:", row.data); // 此处需要更新组件的data数据,已在data中定义 preview_table: {items:[]} // 此处this指向错误,无法访问到Vue组件实例 vm.this.preview_table.items.push(row.data) } }); } reader.readAsText(this.files[0].raw, "UTF-8"); }
问题原因
普通函数的this指向是动态绑定的,由函数的调用方决定:reader.onload的普通函数回调里this指向FileReader实例,内层step的普通函数回调里this指向papaparse的调用对象,都不会指向外层的Vue组件实例,因此无法直接访问组件的data属性。
解决方案
将所有嵌套回调函数替换为箭头函数:箭头函数没有自身的this,会继承外层词法作用域的this指向。外层handlePreview是Vue组件的方法,其this本身指向Vue组件实例,所有内层箭头函数的this都会继承该指向,可直接访问组件data。
正确可运行代码
handlePreview(file,files) { var reader = new FileReader(); // onload改为箭头函数 reader.onload = (reader) => { papaparse.parse(reader.target.result, { worker: true, //header:true, delimiter: ",", download: false, preview: 6, // step回调改为箭头函数 step: (row) => { console.log("Row:", row.data); console.log(this.is_preview_loaded); // 直接用this访问组件data属性 this.preview_table.items.push(row.data); }, complete: (event) => { console.log(event); }, error: (error,file) => { console.log(error); return swal.fire({ title: `文件解析错误`, text: '请确认上传的是合法CSV文件', buttonsStyling: false, icon: 'warning' }) } }); } reader.readAsText(this.files[0].raw, "UTF-8"); },
内容的提问来源于stack exchange,提问作者Dillon Doyle
相关产品推荐
相关产品推荐

