TypeScript基础(六):TS 在 Vue 中的用法,data,生命周期,methods,computed,props,watch,$emit

其实 ts 在 vue 的环境下,我们经常用的一个东西就是上一篇博客讲的装饰器。

装饰器一般情况下有三种用途:

1,装饰整个类。

2,装饰某一个方法。

3,装饰某一个属性。

而这三种用途对 vue 来说,都是很重要的。

其实我们已经认识了第一种装饰器,就是我们平时最常用的:

import { Component } from "vue-property-decorator";

Component 装饰器在目前的 Vue 版本里面是必须的。

就是说,就算你用 class 的写法,你也必须得加这个 Component。

然后我们将 App.vue 里面的东西清空,让我们自己来写。

首先第一件事,我们要在 script 标签上面加上 lang="ts"。

然后,第二件事,就需要引装饰器

需要注意的是:Component 必须装饰在 class 上,否则它没有办法作为一个组件类存在。

然后现在有个问题,我们需要明确,就是这里的 Vue 它到底是什么?

首先,我们可以像以前那么写,直接从 vue 库里面引入。

然后,我们也可以在 decorator 里面去引一个 vue。

可以看到,两种写法都不会报错,也都能出来。

那么这两个 Vue 到底有什么区别呢?

其实 decorator 它这里的 Vue 存在的价值,就是可以让我们少引一个库。

等于说,它替我们在这个 Vue 给引进来了,这样我们就可以少写一个 import。

所以它这里的 Vue 其实并不是一个真正意义上的装饰器,它就是普通的 Vue。

然后我们知道了,所谓“装饰器” 里面的 Vue,其实就是 Vue。我们引哪个都行,它只给提供给我们一个快捷的写法而已。

接下来,我们就真正去把一个普通的 Component 写成 class 的形式。

data 里面的东西,可以全都写成 成员属性。

生命周期 和 methods 里面的东西,可以全都写成 成员方法。

computed 里面的东西,一律写成访问器方法,也就是 get / set。

props 对应的是属性修饰器 @Prop。

我们先来看下原先的写法,方便做一个对比。

创建一个子组件 Cmp,然后在 App 里面引入。

这里需要注意的一点是,组件之间的引用,还是需要借助装饰器 @Component。

这是因为尤大大并没有提供方法来写 components。

所以 components 只能放在装饰器里面。

然后我们在用 class 的形式写出 props:

写完之后我们会发现,浏览器报错了:

它说,你要避免去给属性赋值。

简单来说,子组件 Cmp 中的 a 并不是一个普通的属性。

这里的 a 是父级传给它的 props。

所以我们不能给它初始化的时候赋值。

去掉赋值,就不会报错了。

但是你仔细看, private a 的下面有一个小红线,说明还是有问题的。

别急,先留个印象,我们继续往下看。

那么我们怎么去限制 props 的类型呢?有两种写法。

@Component 里面,就是我们原来的写法。

写在 @Component 里面,和写在 @Prop 里面,两种效果是等同的。

那我们可以在 private a 后面加吗?

我们传的是一个数字,但我们限制的类型是 string。

但是浏览器没有报错,也没其他的反应。

其实它报错了,只不过是在后台报的,还记得上面的那个小红线吗?

这个报错的意思是,你的 a 没有初始值。

好的,那我们重新再加上初始值。

这时候,后台是不报错了,但是前台又报错了,就是我们最开始遇到的第一个问题。

因为 a 是父级传给它的 props。所以我们不能给它初始化的时候赋值。

那么问题就来了:

加了初始值,前台报错。

不加初始值,后台报错。

那你要我怎么做嘛?

其实在 ts 里面有一个东西可以帮助我们来解决这个问题。就是 ! 符号。

那么加上 ! 符号的意思是什么呢?

意思就是,我知道这个 a 没有初始化,没关系,你先放我过去,我以后会初始化它的。

所以 ! 这个标志,是用来告诉 ts,我这个东西以后一定会赋值的,你就不要报错了。

问题解决了,那么我们继续。其实我个人是建议两个 number 都加上的。

@Prop(Number) 其实是 Vue 来做的一个检查。简单来说,如果你给的参数不对,Vue 会报错。

private a: number 这个是属于 Vue 那边已经放它过来了,然后到了真正给它去赋值的阶段,ts 还要再检查一遍。

所以个人建议,2 个都加上比较保险。

然后因为 props 有时候会比较多,所以我们一般都是不换行来写:

那么如果这个 a 既可能是数字,也可能是字符串呢?

@Prop([Number, String]) 这个数组,就是我能接受的类型的数组。

number | string 这个是 ts 里面的语法,联合类型。

那如果我们还需要默认值和验证函数呢?

其实和原先的写法是一样的,我们可以直接写一个 json 进去。

所以,@Prop 其实就是把原来写在 @Component 里面的东西给拆出来了而已。

@Prop 里面还需要注意的一点是:大小写。

后面的 number 大写小写都行,不会报错。

这是因为 number 是 ts 的内置类型,基本类型。Number 是 js 里面的一个 class。

所以它们差不多是等同的。

但是, @Prop 里面只能大写!小写就会报错。

这是因为 number 在 ts 里面,它不是一个东西,它是一个类型。

前面我们有说过,装饰器它本质上就是一个函数,@Prop(number) 相当于在给函数传参。

我们可以传一个数作为参数,也可以传一个类作为参数,都没问题。

但是我们不能传一个类型作为参数。

泛型才可以将类型作为参数传进去,但是函数不行。

watch 对应的是方法修饰器 @Watch 。

首先,我们引入 Watch 这个装饰器。

@Watch('num') 的意思,就是我要监听变量 num。

然后下面声明的 numChange 方法,就是当 num 改变了,就会触发这个方法。

那么,以前的写法里面,还有开始就先执行一次的 immediate,和深度监听 deep。

那么在 class 里面怎么写呢?

直接在 @Watch 里面加参数就可以了。

其实这种写法的 watch 特别适合我们去取数据。

上图中,@Watch 可以直接这样累加的写进来,是很方便的。

当 filters 变了的时候,触发一次 reloadDate 方法。

当 page 变了的时候,触发一次 reloadDate 方法。

所以 @Watch 可以同时监听多种东西,这一点是非常实用的。

并且我们声明了 reloadDate 这个方法,它本身也可以在其他位置用

因为它本身就是一个普通的方法而已,只不过我们在它上面加了两个装饰器而已

所以现在的 @Watch 比以前写法的 watch 要方便很多。尤其是数据获取这一块。

$emit 对应的 @Emit 事件传递

其实这个并不常用,也不实用。

今天有活动,后续的明天写完

发布了63 篇原创文章 · 获赞 3 · 访问量 5176

猜你喜欢

转载自blog.csdn.net/weixin_43921436/article/details/104083472