深入vue3学习(7)+ts 封装useForm+封装useTable
nexttick官方的解释就是:将回调推迟到下一个DOM更新周期之后执行,在更改了一些数据后等待dom更新后立即使用。比如有个需求,点击按钮后修改h2的message, 在修改h2后要获取其高度。一般有三种做法:1 点击按钮后立即获取到h2的高度(X)2 在updated获取 (其他数据更改也会影响)3 在nexttick中获取。nextTick只有在这个方法里面用才有效。别的state更新的时候
nexttick
官方的解释就是:
将回调推迟到下一个DOM更新周期之后执行,在更改了一些数据后等待dom更新后立即使用。
比如有个需求,点击按钮后修改h2的message, 在修改h2后要获取其高度。
一般有三种做法:
1 点击按钮后立即获取到h2的高度(X)
2 在updated获取 (其他数据更改也会影响)
3 在nexttick中获取。
nextTick只有在这个方法里面用才有效。别的state更新的时候不会触发这个函数。只有changeMessage执行了nextTick才会执行。
nextTick的作用是将回调函数加到微任务的队尾上。
vue里面需要做很多任务调度的处理,比如watch,更新dom,生命周期的回调这些,vue里面也有很多任务队列。而nextTick则加入到微任务的队尾上作为最后一个任务,当dom更新完后再去取出来执行。同步的代码也永远不会拿到最新的dom值,因为此时dom还没执行呢。
ts
unkonw与any
unkonw只能赋值给any和unknow类型,而any类型可以赋值给任意类型。
如果一个值未知,最好不要使用any,不然拿去乱用也不会报错,而unknow类型如果拿去赋值给其他类型则会报错。为的就似乎防止乱用
never
表示永远不会发生的值。那么永远不会发生,这个值有啥用呢?
尤大大举了一个例子
上面例子讲了当你写了一些逻辑代码依赖于这个type All的时候,当你的同时改动了里面的值,而没有修改handValue的逻辑的时候,never就登场了,他会直接报错提醒你的同事,要修改All也要修改handValue的逻辑。如果最后没加never,这个代码就通过了,从而造成错误。
联合类型
联合成员,表明可以是联合类型中的一个,
比如
可以是Number或者string
而这种情况只能是其中一个比如,
也可以
也就说,联合类型范围可以往大了扩,但不能往小扩。可以满足AB,但不能一个都不满足。
函数重载
函数的名称相同,但是参数不同的几个函数,就是函数的重载
比如
在其他语言中
会根据具体入参个数调用对应的函数,但是ts不一样
必须写成如下模样
这个add就是调用第一个,、
这个就会找到第二个函数声明。调用第二个add。
interface 与 type
如果是定义非对象类型,建议type
interface 可以重复的对某个接口定义属性和方法
type定义的是别名,别名是不可以重复的
小技巧
多了个d,因为ts会有一个freshness的操作,擦除。
类型的查找
ts的类型推断查找
1 内置类型声明(安装ts的时候顺便自带的.d.ts文件。比如内置对象,dom api等等)
2 外部定义类型声明(一些包,比如@types/axios这些)
3 自己定义类型声明 (自定定义的.d.ts文件)
封装useForm
封装element-plus的form表单实现传入一个配置对象生成一个表单的组件,简单逻辑交互的可以用,复杂逻辑交互的建议还是自己写,不然配置文件也会很复杂。
先看思路,传入一个配置文件,支持四种类型,input password select datepicker 四种组件。
首先定义接口
接口定义完毕
如
再到具体的某个实现,配置对象就配置好了,然后我们直接
v-bind绑定这个对象,内部就会帮助我们解构传进去,如react的<A {…props}>一样方便
然后根据该foremItems遍历
这就是我们将各个组建的options分开的原因,可以直接V-bind很方便。然后每个属性都需要传入一个naem用来做v-model使用。
这样我们的useForm就完成一大半了。
插槽的使用
接着需要完成v-model,双向数据绑定,切记,不可在外部直接扔进来一个reactive对象,然后在内部直接v-model,这样会破坏数据单一流动性。
所以我们可以通过外部传入一个对象。然后通过ref生成一个拷贝的对象,接着在深度监听该对象,一改变就传去外部组件。
react的话的antd库的form表单有一个onValueChange,一旦值改变则触发,所以可以外部传入一个函数,值改变就回调去修改夫组件的值。
而vue的话数据的修改不会放映在内部,所以我们必须通过watch深度监听,将值emit出去,在外部监听,触发回调,修改值,而Vue的v-model组件刚好帮助我们实现这点如。
内部
关键是
watch触发回调,组建的v-model就是这么使用的,不了解的可以先看下官网。
我们坚挺的是对象,所以需要深度监听。
完成:
封装useTable
跟封装useForm一样,useTable也是可以封装的,因为其代码较多且相似,故可以封装起来,但如果逻辑较为复杂的table建议也是自己写会好点。否则配置文件也会很大。
思路
传入配置文件,根据配置文件动态生成表头,然后定义插槽,让外部可以控制展示的内容。
1 接口定义
这些接口并非写死,完全可以根据需要从element-plus的文档加。
然后看组件定义
传入该传入的值。
接着
先不看插槽,我们先把该绑定的属性通过v-bind绑定上去。
然后通过template的v-for去遍历column这个数组,vue3的v-for是建议在外面包一层template,而不是直接写在组件上。
然后看配置文件
我们把整个table和单个colunmn的定义分开来,这样好绑定。
这就是单个column的配置。
然乎看组件使用
直接将我们的tableOptios直接v-bind,让内部去解构。很方便。
看效果
基本表结构就已经有了,我们可以根据自己的需要去实现一写需求,比如固定表头,数据剧中这些。如
可以根据需要去扩展该组件。
插槽的实现
这些特定的数据展示都是根据插槽来实现的。
element-plus的表格自带插槽,header控制表头,default控制展示内容。
后面的scope可以拿到该行的数据。
但是这些内容不应该组件写死,而应该在用的组件去完成,所以我们可以定义插槽,让外部的去实现。
注意,此处的插槽不应该是写死的,而是由外部决定的。
因为每一列的表头可能展示的内容是不一样的,写死的话只能展示一种效果,所以我们由配置文件来传,一旦有hSlotName,表明你要自定义表头了。然后通过Slot的row属性将label传出去,因为表头一般不需要获取该行数据。
通过name绑定对应的插槽,然后拿到传出来的label。效果如图:
表头修改成功。
再看表格的插槽一样的道理,
默认值就是直接展示改行对应的props属性的数据。使用
可以看到是以我们想要的效果渲染了,usetable就差不多完成了。
更多推荐
所有评论(0)