uniapp 里面 let that = this 的由来
这是 ES5老写法,在没有箭头函数的时候用来解决
this丢失问题。
1、问题场景(普通function回调)
exportdefault {
data() {
return {
list: []
}
},
onLoad() {
// 这里的 this → 当前uniapp组件实例,可以访问 this.list
uni.request({
url: 'xxx',
success: function(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',
success: function(res) {
that.list = res.data// ✅用that,操作页面data
}
})
}
that只是变量名,叫_this、vm也完全可以,只是约定俗成叫that。
2、现在UniApp推荐写法:箭头函数,抛弃that
箭头函数继承外层this,不需要额外存that:
onLoad() {
uni.request({
url: 'xxx',
success: (res) => {
this.list = res.data// ✅箭头函数继承onLoad里面的this,直接用this
}
})
}核心总结
1. let that = this的目的:保存外层组件的this,解决普通回调函数内部this指向改变丢失组件实例。2. 什么时候需要写that:回调使用 function () {}普通函数时。3. 使用箭头函数 ()=>{},就完全不需要let that=this。
❗踩坑提醒(很多人写错)
// ❌错误!methods里面不要用箭头函数!
methods:{
test: ()=>{
this.xxx = 1
}
}methods属性值不能用箭头函数,会丢失组件this;但是success、then、setTimeout回调里面优先箭头函数。
对比简表
let that=this | ||
你看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
})
夜雨聆风