Vue.js 2中无法在函数内访问data属性的问题求助
解决Vue.js 2中axios回调无法访问组件data属性的问题
嘿,这个问题我太熟了!本质是this的指向问题在搞鬼,咱们一步步来解决:
问题原因
在axios的.then()和.catch()回调里,你用了普通的function()声明,这种情况下函数内部的this指向的是回调函数自身的执行上下文,而不是Vue组件实例,所以自然会抛出Cannot read property 'showPopUp' of undefined的错误。而mounted钩子是组件实例的方法,里面的this本来就指向组件实例,所以能正常访问showPopUp。
三种解决方法
方法1:使用箭头函数(最推荐)
箭头函数不会创建自己的this,它会继承外层作用域的this(也就是Vue组件实例),代码最简洁:
sendEmail(e) { e.preventDefault(); this.$validator.validateAll(); if (!this.$validator.errors.any()) { let params = new URLSearchParams(); params.append('nameAndLastName', this.nameAndLastName); params.append('email', this.email); params.append('subject', this.subject); params.append('message', this.message); axios.post(this.$apiUrl + `rest/api/public/Contact/contact`, params, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }) // 这里改成箭头函数 .then((response) => { if (response.statusText === 'OK') { console.log(this.showPopUp); this.showPopUp = true; } }) // 这里也改成箭头函数 .catch((error) => { console.log(error); }); } }
方法2:提前保存组件实例的this
在sendEmail方法开头,把组件的this存到一个变量里(比如vm),然后在回调里用这个变量代替this:
sendEmail(e) { e.preventDefault(); // 提前保存组件实例的this const vm = this; this.$validator.validateAll(); if (!this.$validator.errors.any()) { let params = new URLSearchParams(); params.append('nameAndLastName', this.nameAndLastName); params.append('email', this.email); params.append('subject', this.subject); params.append('message', this.message); axios.post(this.$apiUrl + `rest/api/public/Contact/contact`, params, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }) .then(function (response) { if (response.statusText === 'OK') { console.log(vm.showPopUp); vm.showPopUp = true; } }) .catch(function (error) { console.log(error); }); } }
方法3:用bind绑定this指向
给回调函数绑定组件实例的this,强制让回调里的this指向组件:
sendEmail(e) { e.preventDefault(); this.$validator.validateAll(); if (!this.$validator.errors.any()) { let params = new URLSearchParams(); params.append('nameAndLastName', this.nameAndLastName); params.append('email', this.email); params.append('subject', this.subject); params.append('message', this.message); axios.post(this.$apiUrl + `rest/api/public/Contact/contact`, params, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }) // 绑定this到组件实例 .then(function (response) { if (response.statusText === 'OK') { console.log(this.showPopUp); this.showPopUp = true; } }.bind(this)) // 同样绑定this .catch(function (error) { console.log(error); }.bind(this)); } }
总结
这三种方法都能解决问题,其中箭头函数的方式最简洁易懂,也是Vue项目中最常用的写法。修改后,axios回调里就能正常访问this.showPopUp,成功触发弹窗了。
内容的提问来源于stack exchange,提问作者Valor_
相关产品推荐
相关产品推荐

