网上大多数vue+ts的项目都是用的ts+template
但是template对ts的支持有多差,应该都有感受,毕竟用上了ts还用template是没有灵魂的。
那tsx到底哪里比template好呢?
1、template的不能感知到组件内部的属性而tsx是可以
![9027b29985cac3a683a504bc3a5df4f1.png](https://i-blog.csdnimg.cn/blog_migrate/a22e7f56b7d5428124b342d1a271be74.jpeg)
2、tsx更灵活(这个不多说)
3、组件props的提示,很多时候因为手贱写错变量名而找一天的bug。但是tsx能从根源上帮 我们杜绝这些问题。
vue cli3虽然已经对ts做了很大程度的支持,但完全不够用,所以就得自己动起手来搞点事。
我先来介绍一下ts为了jsx而出的几个属性:
![b2552874fb034ac25d0655d5a12a751e.png](https://i-blog.csdnimg.cn/blog_migrate/da1117f526780bbf8b98bca92496081f.jpeg)
这个属性代表所有组件上都有的属性。比如style id 等,这些属性都不会写在props 但是ts回去检查,如果没有就会告诉你 missing xxx。所以我们把这些都有的属性写到这个类型下面。
![f47f3c2dd6c91070a0c4bb825012fd67.png](https://i-blog.csdnimg.cn/blog_migrate/78741981b333c39fd64fe99bdb5daa14.jpeg)
![690614b76b7a05b15a63dd4d93ced565.png](https://i-blog.csdnimg.cn/blog_migrate/b5e5f91a45cd2a9ce24eec9abd23ef6a.jpeg)
这个属性呢,就是你要告诉ts 你要对组件里的哪个属性进行检查。经过我的测试,vue里会对class 里的所有属性和实例后的所有属性进行检查... 这个就比较蛋疼了。
我的做法是这样:指定ElementAttributesProperty 属性对组件的$props属性进行检查
![652cdc80dbe491f4ed1dcfdea696559b.png](https://i-blog.csdnimg.cn/blog_migrate/a219c65f1c64c882eb2b4e8ee65d9aa5.jpeg)
但是我们没办法对$props进行类型声明啊。
我起初的做法是这样的:
![5d1421e76ba7cb511541c39a334e5755.png](https://i-blog.csdnimg.cn/blog_migrate/fc823c5e31b649451686f5ed29d7a347.jpeg)
也是行的通的。但是每个组件里面都得写一遍,这不符合我处女座的性格啊。
so:我们能不能像react那样传递一个泛型P进去赋予$props类型呢。
![82d863546682dc8957f63f80154228ad.png](https://i-blog.csdnimg.cn/blog_migrate/f3cc20d8529aa69044376cdf05866965.jpeg)
此时我们可以这样
![3c66196a6b6f25842a3e7cc2cf3dba1a.png](https://i-blog.csdnimg.cn/blog_migrate/8080c24694cce6e4271693ef6dfc35e8.jpeg)
之前我们的props的类型不仅需要interface 去声明一遍 在组件里每声明一个props 都得把类型再写一遍,本来写接口类型就已经很蛋疼了,写两遍不是要了亲命啊!
但是此时我们使用
![8b3a54df64cdb04570cb594b77b3e239.png](https://i-blog.csdnimg.cn/blog_migrate/543410afe3e2c91723ee0883483cc2f0.jpeg)
perfect!!!!
介绍完类组件,接下来就是函数式组件了。
可能在vue里使用函数式组件的人不多,但是函数式组件真的很好用呢。(最大的好处就是不用再组件里注册props,毕竟懒!)
![0c41b17e9e695ded747df6b3b536b633.png](https://i-blog.csdnimg.cn/blog_migrate/675ea92791e8324d33ec24e3e8490b02.png)
react里默认第一个参数是props ts也会对第一个对象里的所有属性进行检查。
但是vue就又蛋疼了!
![3d32c167f11b62f17814e72a1c1035a8.png](https://i-blog.csdnimg.cn/blog_migrate/0c730ddafb8a179b2acc644378a64bc8.jpeg)
vue函数式组件的第一个参数里包含了这么多属性,而props属性是属性的内部属性,
更蛋疼的是ts好像没有像class组件那样 可以指定属性去检查。这怎么办呢......
![b4bb44f1701200b1123edfdd71400018.png](https://i-blog.csdnimg.cn/blog_migrate/c659b8aa49d9ba97996867c1b54a8c7e.jpeg)
我将ctx里的类型全部转化为可选 然后传递给props的泛型P和ctx合并,此时的我们需要被ts检查的属性全都存在于ctx对象上了,perfect。。。
![078d713eea2af64ffec5398f37f9a328.png](https://i-blog.csdnimg.cn/blog_migrate/04eafdb604975c054344616de9d5431e.jpeg)
![cbd9ef45cc4ac378590bf0b09d781eb0.png](https://i-blog.csdnimg.cn/blog_migrate/46636c5c10f450684c4f8b18e5572e21.jpeg)
写一个对antd-vue组件二次封装的函数式组件
![c993a7fff56504aea2eb00f475a92710.png](https://i-blog.csdnimg.cn/blog_migrate/2865d397b419c9ecb8fefa3e76a89cf2.jpeg)
antd 的table组件是么有tooptip的,而且algin对其方式应该是可以统一设置的 但是api没有提供, 所以我用函数式组件 拦截了组件的props 经过改动 再传给原组件 。
有时候我们有很多的props需要传递 ,不想在组件里一一定义,但是组件又有内部状态,还需要生命周期怎么办呢? look↓
![c0428f64fb07a8d24d15fc8f15595319.png](https://i-blog.csdnimg.cn/blog_migrate/4558a0d33b7c2f98c502963ab5a57b74.jpeg)
所有的props都从上层的函数式组件获取,省去了定义props的麻烦。
而且组件有自己的生命周期状态,prefect。。。。
总结:使用 TS 来实现对 vue 组件进行正确的类型检查其实是相当难的,但是谁让我聪明呢,嘻嘻。