6.28工作总结:
今天最大的收获是实现了antd Table组件的表头置顶。所谓的表头置顶,就是随着滚轮的滑动当table长度无限的时候table的表头能够置顶。这个对比上次的弹窗中的列表其实是简单了很多,真的实现起来只需要一个属性,sticky就行了,sticky之后,然后设置.ant-table-sticky-holder
中的z-index
和top
的长度和宽度就可以了,其实还是很简单的,注意此时的top应该设置为top: xxx px !important;不然设置的属性没有效果
今天发现了useEffect的缺点所在。他的执行栈其实跟setState的callBack并不一致。所以我决定换用useLayoutEffect,等所有数据彻底改变后,再去调用useEffect中的变量,渲染页面。感觉就会好很多。今天换用了新的函数来监听整个页面的渲染情况
表格中的情况
useEffect(()=>{
if(page === 1){
getData()
}else if(page > 1 && moreLoading ){
getData()
}
},[page,moreLoading,tags])
model中的情况
useUpdate(() => {
if (deepEqual(anchorDetail,brandId.current)) {
return;
} else {
brandId.current = anchorDetail;
if (page !== 1){
getAnchorInfo();
setPage(1)
}else {
getAnchorInfo();
getCollectId()
}
}
}, [anchorDetail]);
之前一直担心的page为1不改变后来发现是想多了,如果page === 1,那么页面会走另一个getPage,也不会产生bug,这应该是到目前为止较好的写法了。其实最好还是setState来处理,不过这个确实还是得用hooks,痛并快乐吧
复制代码
6.29工作总结:
今天尝试重构了之前的代码,将之前逻辑复杂的多个组件的嵌套使用新的dva来管理整个状态。发现其实也是很复杂的,因为table的数据牵动不止是data一个,还有hasMore,page,loading等等,所以真的要使用dva来管理,我需要有多个参数变量来保存,其实是得不偿失的。最好的我思考还是得用useReducer和content,下次如果还遇到了这个场景,我一定要试试。
这里给出dva中处理一般state和异步state的方法:
- 一般的
state:{
...
count:1
},
reducer{
addCount(state){
const {count} = state
return {...state,count:count+1}
}
}
复制代码
- 特殊的
state:{
obj:{}
},
effect{
*fectchObj({payload},{call,put}){
const res = yield call(()=>{
fetch(url)
},payload)
if(res && res.status === 0){
yield put({
type:"saveObj",
payload:res
})
}
}
},
reducer{
saveObj(state,action){
return {...state,obj:action.payload || {} }
}
}
复制代码
6.30工作总结:
今天我遇到一个需求,需要页面跳转的时候重新加载一个新的页面,并且在新的页面中如果之前的页面时登录状态,那么在新的页面中也需要处于登录的状态,这个需求我之前完全没有遇到过,碰到了之后有点懵逼。
观看之前实现的源码,我才知道做这个的思路是什么:
首先,我需要去要跳转的页面中去查找我要登录的页面是否已经处于登录的状态,如果已经登录了,那么我这边就不用再进行一次登录。如果那边并没有登录,那么我这边需要取得跳转到那边需要调用的接口,调用接口之后,浏览器就会记住登录的状态,从而在新的页面中自己就会处于登录的状态。
之前这个需求一直解决不了,我也调用了登录的接口,也发现登录的接口在新的页面中其实已经处于了登录的状态,但是我还是无法实现登录的状态。我当时很迷茫,不知道为什么会这样(到现在为止我都不知道为啥会这样)。所以我想出了另一个办法。在我登录前首先用页面进行一个预载的登录,也就是windows.open(url,"_blank")
,这样首先页面就会打开一个空白的网页,此时我们可以将要用的url传递为需要登录的请求,然后这样浏览器自己就会记下要发送的请求,从而在下次请求到页面之后进行页面的渲染,不过为了防止太快导致页面没有办法进行渲染所以需要配合定时器来使用。(后来想了想如果我们用promise其实会更好一点)。
然后今天的收获在于:
- 知道了在页面中产生一个新的页面的办法:
- windows.open
- 用dom做一个a标签,然后点击
const anchor = document.createElement("a")
const body = document.querySelector('body')
anchor.href = window.URL.createObjectURL(url)
anchor.download = filename
复制代码
- 知道了二维码扫描的时候其实是会产生一个unionId(也可能是别的),通过这个Id去数据库中查找是否有相同的id,如果有就返回,没有就不理会
7.1工作总结:
今天我知道了一个tips:我们可以通过给img加属性object-fit:cover
使得图片变形之后依然处于居中的状态。
然后今天做的最大的事情就是将所有的Table组件进行重构,将请求,各种数据放在组件中,然后用一个url通过外面去传递,然后将各种查询参数通过一个对象传输过来,如果需要改变的话就用一个对象对比的方法写在useEffect中,这次重构是我写到现在为止最满意的写法,之后所有需要改变的参数只要都在参数对象中改变,Table组件就会自己对比,自己发起请求,再也不需要手动各种去判断条件了。明天过来我进行重构
7.2工作总结:
今天我对之前写的所有二面进行了重构,顺带又将Input的组件也进行了重构,真正体会到了组件化的好,很多之前繁琐复杂的组件我们再也不用写第二遍以上了。
这次总结带来的经验,以后凡是符合以下条件的,我们直接采用封装策略:
- 重复在代码中出现3次及以上的
- 代码中除了请求部分其他大部分相同的
- 一个项目中有明确组织的,哪怕再小的组件,我们也要尽可能进行封装,这样有利于代码的统一化
- 代码量超过400行以上,或者多次出现useState等定义state的情况的,这种一般都是state使用过多了,看见了,没说的,封装