vue3 reactive 包裹 ref 导致取值 undefined

有点不知道该如何描述用一句话描述这个现象。先来看一段代码:

import { ref, reactive } from 'vue'

class T{
  a = ref(1)
  getA() {
    return this.a.value
  }
}

const t = new T()

const proxyT = reactive(t)

console.log('t.getA:', t.getA())
console.log('proxyT.getA:', proxyT.getA())

在上面这段代码里,两个 getA 分别返回什么值呢?直觉告诉我都是 1。但实际上,第一个是 1,第二个是 undefined。

出现这个问题,是因为 reactive 包裹 ref/computed 的时候会自动解包。这对于嵌套响应式对象去除 .value 很好用。但在代理对象的时候,proxy(vue3 的底层原理)会导致被代理对象的 this 指向代理对象。即 proxyT 的 getA 里的 this 指向的是 proxyT,而 proxyT 里的 a 被解包了,取值不需要 .value,所以得到 undefined。

那这个问题如何解决呢?好办,constructor 里绑定 this 就可以了。

class T{
  a = ref(1)

  constructor() {
    this.getA = this.getA.bind(this)
  }
  
  getA() {
    return this.a.value
  }
}