页面布局
这里提供的布局只是一种布局思路或者说策略,需要根据实际项目进行调整。
页面分割为三块内容,头部-header,填充内容- page-content,底部-footer,这三部分都不需要使用定位就可以固定在顶部和底部,这样就不会有软键盘弹出时fixed失效的问题。可以滚动的只有填充内容- page-content部分。
根元素的样式:
需要注意的是,根元素设置了高度(屏幕高度),宽度(屏幕宽度),定位,以及元素溢出屏幕时隐藏而不是滚动。
头部-header的样式:
修改header的高度时,需要在.page-content和.page-content.no-footer样式中修改height减去的高度。
底部-footer的样式
修改footer的高度时,需要在.page-content样式中修改height属性减去的高度。
填充内容- page-content的样式:
只需要头部添加类名header ,填充内容添加类名page-content,根据是否有头部和底部添加对应的类名,底部添加类名footer,这个布局就完成了。
page-content的高度=屏幕高度-头部高度-底部高度,这样保证三块内容高度相加等于根元素的高度且不溢出,page-content设置了Y轴方向的滚动,同时具有position属性和高度,所以其子元素除了fixed定位外的所有定位不会是body和根元素,子元素使用百分比设置高度也会生效。需要X轴滚动的情况,在滚动区域外加一层div,不建议修改这个类。
样式上定义了没有头部时page-content的高度和没有底部时page-content的高度,没有头部也没有底部的页面,请不要用这个高阶组件,自己定义一个样式吧,当然,添加一个.page-content.no-header.no-footer的类名也可以。
关于适配样式
适配需要留出空白的部分,只需要调整根元素的高度或者内边距,和填充内容的高度就可以完成,以IPhoneX适配为例,需要在底部留出20px的高度,这个时候只需要让根元素的高度和填充内容page-content的高度都减少20px就可以了。
使用高阶组件
如果每个页面都需要手动添加这些样式是比较麻烦的,尤其是当需要修改或者添加一些公共类名的时候,所以有了高阶组件PublicPage.jsx,PublicPage组件内头部显示内容使用的Header组件,底部显示内容使用的EdTabBar组件,填充内容显示的是传进来的组件,头部显示内容和底部显示内容可以根据实际项目需要进行修改。
显示的控制:UI库中,header默认是一定会显示的,后续可能会做一些优化,把头部也变成通过读取配置控制显示,底部是根据传参footerKey,读取底部内容的配置footerConfig,获取底部显示内容(如问文字,图标,路由)。
参数传递:像是Header组件需要传入title和backFn,为了PublicPage组件能够简便的从传入的组件中获取参数,除了函数外,都是从静态变量中获取,比如
为什么不通过静态变量的方式获取组件内的函数呢?因为静态变量无法获取到组件任何的props和state,所以使用了通过ref的方式,如下:
但是,ref这种方式不适用于函数声明的组件,所以高阶组件还接收一个参数对象pageParam,pageParam的属性名与组件设置的静态变量一致,且行为一致,函数声明的组件需要设置pageParam.isFunComponent = true,此时不会创建ref,且Header组件的backFn和rightFn触发时执行 window.history.back()。
组件静态变量说明:
属性名 | 作用 |
title | Header组件的children,默认值为空 |
isGoback | Header组件isGoback的属性值,默认为true |
right | Header组件right的属性值,无默认值 |
footerKey | 底部配置footerConfig的key,若footerKey或footerConfig[footerKey]布尔值为false,则页面不显示底部 |
高阶组件内还可以做什么?
这个高阶组件可能拿到项目里还需要少量更改,因为引入了Header和EdTabBar这两个组件,大多数时候替换头部和底部为项目自己的组件就可以了。
PublicPage.jsx文件内的footerConfig,是底部显示内容的配置,需要显示底部的页面只需要设置footerKey就可以了。
高阶组件内还添加了componentDidCatch声明周期,用于捕获页面级别的错误,同样的,只需要在高阶组件内写一遍就可以了。
在AppRouter中可以看到有两个路由配置,区别是RouterHOCConfig中的页面会使用高阶组件,RouterConfig中的页面不会使用高阶组件,为了使用方便,封装了Router,代码如下:
这样页面就和平时开发的就没有区别了,只需要设置一些静态变量就可以,而且不需要每个页面引入Header组件。
Last updated