TypeScript在Vue3.0的Ref类型中的实践

# 一、Ref的定义

vue3.0中的响应式原理是基于proxy做的,而使用proxy的前提是,我们要代理的是对象而不是基本类型数据。如果我们用如下方式定义一个响应式的数据,count的改变是无法变监听拦截到的:

![](//upload-images.jianshu.io/upload_images/5791681-426b297925000a81.png?imageMogr2/auto-orient/strip|imageView2/2/w/362/format/webp)

错误地将基本类型定义成响应式

这时候,就需要ref来先讲基本类型包装成{value: 基本类型数据},然后再对这个包装对象进行响应式处理。

# 二、Ref类型的实现

## 第一版本:

最容易想到的实现方式如下:

![](//upload-images.jianshu.io/upload_images/5791681-5feda3797decbf44.png?imageMogr2/auto-orient/strip|imageView2/2/w/703/format/webp)

Ref类型的第一版实现

简单解释下,首先定义一个Ref类型,这个类型的value可以是任意类型(any),然后再定义一个ref的函数,接受一个任意类型的参数T,再将T封装成Ref类型返回。由上图我们可以看到,我们输入了number类型的值,由泛型的反向推到我们可以知道,返回的count是Ref<number>,所以count.value为number类型。

## 第二版本:

考虑到ref嵌套的问题,我们期望直接通过count.value获取,而不是count.value.value.value.value。这时候我们需要对一版本进行改进。

![](//upload-images.jianshu.io/upload_images/5791681-7a06af28d3aa177a.png?imageMogr2/auto-orient/strip|imageView2/2/w/303/format/webp)

ref嵌套的问题

### 步骤一:extends

对于改进,首先想到的是利用extends关键字进行条件判断:

![](//upload-images.jianshu.io/upload_images/5791681-617aa69e26f227cf.png?imageMogr2/auto-orient/strip|imageView2/2/w/391/format/webp)

步骤一

由上图可是,对于ref函数的返回时,我们进行了条件判断,**_如果传入的参数是Ref类型,函数将原封不动返回这个Ref类型,否则需要将T包装成Ref类型再进行返回。_**

这样针对ref(ref(2))这种嵌套场景,首先内层的ref(2)返回的是Ref<number>类型,然后外层的ref通过判断,将内层的Ref<number>类型直接返回。这返回值依然形如{value:number}的对象。而不是{value:{value:number}}。

文章作者: J_da
本文链接:
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 A2PX空间
默认分类 TS
喜欢就支持一下吧