乐于分享
好东西不私藏

每天一个知识点:uniapp发送请求前常常会用let that=this为了啥?

每天一个知识点:uniapp发送请求前常常会用let that=this为了啥?

uniapp 里面 let that = this 的由来

这是 ES5老写法,在没有箭头函数的时候用来解决 this 丢失问题。

1、问题场景(普通function回调)

exportdefault {
data() {
return {
list: []
    }
  },
onLoad() {
// 这里的 this → 当前uniapp组件实例,可以访问 this.list
    uni.request({
url'xxx',
successfunction(res) {
// ⚠️这里是普通 function,success回调内部this不再是组件实例!
console.log(this// this 不再指向页面,拿不到 this.list
this.list = res.data// ❌报错,赋值无效
      }
    })
  }
}

success:function(){} 是普通函数,函数调用的时候this发生改变,不再是Vue组件实例,无法操作data里面的数据。

老方案:let that = this

把外层组件的this保存给变量that,回调内部使用that访问组件实例。

onLoad() {
let that = this//把页面组件实例存到that变量
  uni.request({
url'xxx',
successfunction(res) {
      that.list = res.data// ✅用that,操作页面data
    }
  })
}

that只是变量名,叫_thisvm也完全可以,只是约定俗成叫that。

2、现在UniApp推荐写法:箭头函数,抛弃that

箭头函数继承外层this,不需要额外存that:

onLoad() {
  uni.request({
url'xxx',
success(res) => {
this.list = res.data// ✅箭头函数继承onLoad里面的this,直接用this
    }
  })
}

核心总结

  1. 1. let that = this 的目的:保存外层组件的this,解决普通回调函数内部this指向改变丢失组件实例
  2. 2. 什么时候需要写that:回调使用function () {}普通函数时。
  3. 3. 使用箭头函数()=>{},就完全不需要let that=this

❗踩坑提醒(很多人写错)

// ❌错误!methods里面不要用箭头函数!
methods:{
test()=>{
this.xxx = 1
  }
}

methods属性值不能用箭头函数,会丢失组件this;但是success、then、setTimeout回调里面优先箭头函数。

对比简表

写法
内部this
处理方式
success: function(res){}
this指向请求回调上下文,不是页面
let that=this
success: (res)=>{}
继承onLoad外层的this,就是页面实例
直接用this,不用that

你看CRMEB老版本uniapp源码大量看到let that = this,就是早期大量使用普通回调函数;新版本代码基本全部改成箭头函数,很少看到that。

补充:Promise的then同样道理

// 旧写法
let that = this
api.getInfo().then(function(res){
    that.info = res.data
})

//现代写法,箭头函数
api.getInfo().then(res=>{
this.info = res.data
})