欢迎来到皮皮网官网

【来疯美颜源码】【问道最新端源码】【博彩类游戏源码】单列布局源码_什么是单列布局

时间:2024-12-28 11:57:16 来源:滴滴小程序源码

1.Element 2 组件源码剖析之 Layout (栅格化)布局系统
2.移动端前端布局(移动端前端布局是单列什么)
3.Flutter(四)之Flutter的布局Widget
4.没写过复杂 React 组件?来实现下 AntD 的 Space 组件吧

单列布局源码_什么是单列布局

Element 2 组件源码剖析之 Layout (栅格化)布局系统

       深入剖析 Element 2 组件中的栅格化布局系统,此系统通过基础的布局分栏,为开发者提供快速简便的源码布局解决方案。本文将带你探索栅格系统如何通过行(row)与列(col)组件实现布局的什单灵活性与高效性。我们关注的列布是如何创建一致、规范、单列来疯美颜源码简洁的布局网页布局,提升用户体验。源码

       网页栅格化布局是什单提升页面设计与开发效率的关键工具,它让页面布局更加统一且易于复用。列布Grid.Guide、单列Bootstrap 等工具提供了灵活的布局栅格系统,允许开发者自定义最大宽度、源码列数及边界,什单以生成优化的列布栅格方案。Element 2 则借鉴 Ant Design 的理念,采用栅格系统基础上的等分原则,以应对设计区域内的大量信息收纳需求。

       栅格化布局系统的核心在于行(row)与列(col)组件。组件行(row)作为列(col)的容器,通过渲染函数构建,支持自定义HTML标签渲染,允许开发者根据需要灵活定制布局结构。列(col)组件则通过渲染函数构建,提供丰富的配置选项,包括间距、对齐方式等,以满足不同布局需求。

       行(row)组件支持通过属性动态调整样式与自定义标签,如gutter属性用于设置栅格间隔,type属性可选择使用Flex布局以实现更灵活的布局模式。justify与align属性分别控制Flex布局下的水平与垂直对齐方式,提供多种排列选项。此外,组件还通过计算属性计算样式,以抵消列(col)组件的内边距,确保布局的精确性。

       列(col)组件则通过渲染函数构建,支持自定义标签渲染,同时包含多个配置属性,如span用于指定列的宽度,gutter属性获取父组件row的间距设置,并根据此计算自己的内边距。组件还动态计算样式,以实现栅格、间隔、左右偏移的灵活调整。响应式布局特性使组件能够在不同屏幕尺寸下自动调整布局,提供适应性设计。

       通过组件的渲染函数与属性配置,Element 2 的问道最新端源码栅格化布局系统实现了一种高效、灵活且可扩展的布局解决方案,为开发者提供了强大的工具来构建响应式、美观且功能丰富的网页布局。

移动端前端布局(移动端前端布局是什么)

       前端布局————长度比例

       这是一些不太惹人注意的知识,烂没但是掌握了他会对你的前端不具有很大帮助。

       在前兆亩端布局时,我们将长度单位分为两种,一种是绝对单位,一种是相对单位。

       上述这些就是绝对单位,这些单位在现实中有绝对定义,不会随着你的布局平台大小比例变化而变化(ps:1inch=2.cm)

       没错,你没有看错,px是一个相对单位,px是Pixel的缩写,代表的是图像上最小的一个点的大小,他会因为图像大小的不同而改变,比如x的一张图,当他的长宽扩大一倍,而分辨率不变(即x),那么他的每个像素的大小都将扩大一倍

       通常我们所指的4.5寸、5,0寸这些手机屏幕的大小指的是手机屏幕对角线的距离(只包括可显示部分,边框部分不包括)

       我们在开发移动设备的网站时,最常见的的一个动作就是把下面这个东西复制到我们饥猜纳的head标签中:↓↓↓

       该meta标签的作用是让当前viewport的宽度等于设备的宽度,同时不允许用户手动缩放

       (ps:移动端下定宽写法:viewportwidth=定值(设计稿宽),我们不设置缩放相关属性,移动端浏览器会自动缩放页面以适配屏幕)

       rem和em单位是由浏览器基于你的设计中的字体大小计算得到的像素值。em单位基于使用他们的元素的字体大小。rem单位基于html元素的字体大小。em单位可能受任何继承的父元素字体大小影响。rem单位可以从浏览器字体设置中继承字体大小。

       (ps:一般情况下,不要给字体大小用rem)

       现在前端流行什么页面布局方式?

       前端常用页面布局分为下面几种:

       1.静态布局

       给页面元素设置固定的宽度和高罩隐度,单位用px。窗口发生变化时,会出现滚动条,内容会被遮挡。

       优点:简单方便,不存在兼容问题。

       缺点:网页无法根据用户设备屏幕的宽度进行自适应。

       2.流式布局

       也叫%布局。宽度单位为百分比。流式布局常用的设计答孙模板:左侧固定+右侧自适应,左右固定宽度+中间自适应。

       优点:可以适应不同尺寸的屏幕

       缺点:如果屏幕尺度跨度太大,那么在相对其原始设计而言过小或过大的屏幕上不能正常显示。因为宽度使用%百分比定义,但是高度和文字大小等大都是用px来固定

       3.响应式布局

       使用meta标签设置,页面元素宽度随窗口调整自动适配。采用自适应布局和流式布局的综物举厅合方式,为不同屏幕分辨率范围创建流式布局。博彩类游戏源码

       优点:适应pc和移动端,如果足够耐心,效果完美

       缺点:

       (1)媒体查询是有限的,也就是可以枚举出来的,只能适应主流的宽高。

       (2)要匹配足够多的屏幕大小,工作量不小,设计也需要多个版本。

       4.弹性布局

       就是采用css3中的flex属性。

       优点:简单、方便、快速

       缺点:CSS3新特性,浏览器兼容性非常头疼。而且手机浏览器对flex的支持也不是很理想。

移动端几种常见的界面设计布局

       这里我画了几种移动端常见的页面布局和他们的各自特点:

       1,列表式布局

       2,陈列式布局

       3,九宫格式布局

       4,选项卡式布局

       5,轮播图式布局

       6,伸展式布局

       7,抽屉式布局

       8,弹出框式布局

       9,横向拓展式布局

       、多面板式布局

       1,列表式布局

       特点:

       内容从上向下排列,导航之间的跳转要回到初始点。

       优点:

       1、层次展示清晰

       2、视觉流线从上向下,浏览体验快捷

       3、可展示内容较长的菜单或拥有次级文字内容的标题

       不足:

       1、导航之间的跳转要回到初始点

       2、同级内容过多时,用户浏览容易产生疲劳

       3、排版灵活性不是很高

       4、只能通过排列顺序、颜色来区分各入口重要程度

       场景:

       列表菜单适合用来显示平级菜单,且较长或拥有次级文字内容的标题

       2,陈列式布局

       特点:

       布局比较灵活,设计师可以平均分布这些网络,也可根据内容的重要性不规则分布,相对列表式,其优点在于同样的高度下可放置更多的菜单,更具有流动性,曝布流就属于其中一种。

       优点:

       1、直观展现各项内容

       2、方便浏览经常更新的内容

       不足:

       1、不适合展现顶层入口框架

       2、容易形成界面内容过多,平安保险源码显得杂乱

       3、设计效果容易呆板

       场景:

       适合以为主的单一内容浏览型的展示

       3,九宫格式布局

       特点:

       相比陈列馆式,布局比较稳定为一行三列式布局。

       优点:

       1、清晰展现各入口

       2、容易记住各入口位置,方便快速查找

       不足:

       1、菜单之间的跳转要回到初始点

       2、无法向用户介绍大概的功能,只能点击进去才能获知,初始状态不如列表式明朗

       3、容易形成更深的路径

       4、不能直接哗吵展现入口内容

       5、不能显示太多入口次级内容

       场景:

       适合入口比较多的展示,而且导航之间切换不是很频繁的情况,也就是业务之间相对独立,没有太多的瓜葛。

       4,选项卡式布局

       特点:

       导航一直存在,具有选中态,可快速切换到另一个导航。

       优点:

       1、减少界面跳转的层级

       2、分类位置固定

       3、清楚当前所在的入口位置

       3、轻松在各入口间频繁跳转且不会迷失方向

       4、直接展现最重要入口的内容信息

       不足:

       功能入口过多时,该模式显得笨重不实用

       场景:

       大部分放在底部,方便用户操作,切换的时候,选中状态高亮显示,有少数放在顶部。适合分类少及其内容乱陪侍同时展示,导航菜单项数量为3-5个;各导航菜单项之间内容/功能有显著差异;用户在各个导航选项之间需要非常频繁的切换操作

       5,轮播图式布局

       特点:

       重点展示一个对象,通过手势滑动按顺序查看更多

       优点:

       1、单页面内容整体性强,聚焦度高

       2、线性的浏览方式有顺畅感、方向感

       不足:

       1、受屏幕宽度限制,它可显示的数量较少,需要用户进行主动探索

       2、由于各页面内容结构相似,容易忽略后面的内容

       3、不能跳跃性地查看间隔的页面,只能按顺序查看相邻的页面

       场景:

       适合数量少,聚焦度高,视觉冲击力强乱拦的blheli电调 源码展示

       6,伸展式布局

       特点:

       能在一屏内显示更多的细节,无需页面的跳转

       优点:

       1、减少界面跳转的层级

       2、对分类有整体性的了解

       3、清楚当前所在的入口位置

       不足:

       分类位置不固定,当展开的内容比较多时,跨分类跳转不方便

       场景:

       适合分类多及其内容同时展示

       内容展示的信息多

       7,抽屉式布局

       特点:

       突出核心功能,隐藏其它功能。

       优点:

       1、不占用宝贵的屏幕空间,让用户首先能聚焦于内容

       2、导航的菜单项目不受数量限制,应用的所有信息组织入口都可以加入到抽屉导航中

       3、扩展性强,配置灵活,一些常用的快捷操作功能和低层级界面入口也能直接放置进抽屉导航中

       不足:

       1、隐藏框架中其他入口、用户需要一定记忆成本

       2、对入口交互的功能可见性要求高

       3、容易与应用内的其他交互模式冲突,比如侧滑手势操作

       场景:

       适合功能较多,信息结构较复杂的产品,用户的注意力聚焦在主信息流的浏览上,不用频繁切换“子产品模块”,且扩展性比较好

       8,弹出框式布局

       特点:

       没有跳出感,适合内容比较少和简单操作的呈现。

       优点:

       1、在原有界面上进行操作,不必跳出界面,体验比较连贯

       2、在用户需要的时候才显示(重要提示除外),不主动干扰

       不足:

       1、显示的内容有限

       场景:

       适合内容较少的显示

       9,横向拓展式布局

       特点:

       节省空间,可使用箭头,圆点或显示不全的告诉用户还有更多的内容可查看。

       优点:

       1、查看更多内容不必跳出界面,体验连贯。

       2、节省空间。

       不足:

       横屏宽度有限,更多的内容有数量上限制。

       场景:

       适合或信息组块更多的展示方式。

       、多面板式布局

       特点:

       能同时呈现比较多的分类及内容。

       优点:

       1、减少界面跳转的层级

       2、对分类有整体性的了解

       3、分类位置固定

       4、清楚当前所在的入口位置

       不足:

       1、界面比较拥挤

       场景:

       适合分类多及其内容同时展示

       内容展示的信息不多

       以上都是基本布局,在实际的设计中,我们需要结合具体的数据结构特点选用合适的布局,把不同的布局像搭积木一样组合起来完成复杂的界面设计,要考虑信息结构、重要层次以及数量上的差异,提供最适合的布局,以增加产品的易用性和交互体验。

前端常见布局方式

       常见的布局方式

       常见的布局这么几种单列水平居中布局,一列定宽一列自适应布局,两列定宽一列自适应布局,两侧定宽中间自适应三列布局。

       一列定宽一列自适应

       定位布局

       左边的宽度写死,右边盒子使用定位拉伸法实现,left等于左边盒子的宽度,right等于0

       .left-box{ width:px;?如核}

       .right-box{ ?position:absolute;left:px;right:0;}

       或者左边的定位写死宽度,右边的写padding-left等于左边的宽度(常用一点)

       .left-box{ width:px;?position:fixed;height:%;?}

       .right-box{ ?padding-left:px;}

       浮动布局

       左边的宽度写死并且浮动,右边盒子写overflow:hidden;利用的是创建一个新的BFC(块级格式化上下文)来防止文字环绕的原理来实现的。BFC就是一个相对独立的布局环境,它内部元素的布局不受外面布局的影响

       .left-box{

       width:px;

       height:px;

       float:left;

       background:#f;

       }

       .right-box{

       height:px;

       overflow:hidden;

       background:#cff;

}

       两列定宽一列自适应上面的布局方式同样适用

       常见的三列布局一般使用圣杯布局和双飞翼布局。

       圣杯布局和双飞翼布局

       两者都属于三列布局,是一种很常见的页指核面布局方式,

       三列一般分别是子列、主列和附加列,其中子列一般是居左的导航,且宽度固定;主列是居中的主要内容,宽度自适应;附加列一般是广告等额外信息,居右且宽度固定。

       圣杯布局

       div?class="container"?

       div?class="main"/div?

       div?class="sub"/div?

       div?class="extra"/div?

       /div

       .container?{ ?

       padding-left:px;

       padding-right:px;

       }

       .main?{ ?

       float:left;?

       width:%;

       height:px;

       }

       .sub?{ ?

       position:relative;?

       left:-px;

       float:left;?

       width:px;

       height:px;

       margin-left:-%;

       }

       .extra?{ ?

       position:relative;?

       right:-px;

       float:left;?

       width:px;

       height:px;

       margin-left:-px;

       }

       双飞翼布局

       div?class="main-wrapper"?

       渣逗掘div?class="main"/div?

       /div

       div?class="sub"/div?

       div?class="extra"/div?

       .main-wrapper?{ ?

       float:left;?

       width:%;

       }

       .main?{ ?

       height:px;

       margin-left:px;

       margin-right:px;

       background-color:?rgba(,0,0,.5);?

       }

       .sub?{ ?

       float:left;?

       width:px;

       height:px;

       margin-left:-%;

       background-color:?rgba(0,,0,.5);?

       }

       .extra?{ ?

       float:left;?

       width:px;

       height:px;

       margin-left:-px;

       background-color:?rgba(0,0,,.5);?

       }

       俩种布局方式都是把主列放在文档流最前面,使主列优先加载。

       两种布局方式在实现上也有相同之处,都是让三列浮动,然后通过负外边距形成三列布局。

       两种布局方式的不同之处在于如何处理中间主列的位置:圣杯布局是利用父容器的左、右内边距定位;双飞翼布局是把主列嵌套在div后利用主列的左、右外边距定位。

       其他的话还有

       flex布局

       Flexbox又叫弹性盒模型。它可以简单使用一个元素居中(包括水平垂直居中),可以让扩大和收缩元素来填充容器的可利用空间,可以改变源码顺序独立布局,以及还有其他的一些功能。

       Flex布局是我最喜欢的布局,合理使用它能够大大减少布局方面的工作,例如以上列举的三列布局也可以使用flex轻松实现。此外在移动端使用flex也比较常见。

       响应式布局

       网页可以自动识别设备屏幕宽度,根据不同的宽度采用不同的CSS的样式,从而达到兼容各种设备的效果。

       响应式布局使用媒体查询(CSS3MediaQueries),根据不同屏幕分辨率采用不同CSS规则

       流式布局

       流式布常见的就是bootstrap了它提供了一套响应式,移动优先的流式栅格系统(gridsystem),将屏幕分成列来实现响应式的。它的实现原理非常简单,MediaQuery加上float布局

Flutter(四)之Flutter的布局Widget

       ä¸€.单子布局组件

       å•å­å¸ƒå±€ç»„件的含义是其只有一个子组件,可以通过设置一些属性设置该子组件所在的位置信息等。

       æ¯”较常用的单子布局组件有:Align、Center、Padding、Container。

1.1.Align组件1.1.1.Align介绍

       çœ‹åˆ°Align这个词,我们就知道它有我们的对齐方式有关。

       åœ¨å…¶ä»–端的开发中(iOS、Android、前端)Align通常只是一个属性而已,但是Flutter中Align也是一个组件。

       æˆ‘们可以通过源码来看一下Align有哪些属性:

constAlign({ Keykey,this.alignment:Alignment.center,//对齐方式,默认居中对齐this.widthFactor,//宽度因子,不设置的情况,会尽可能大this.heightFactor,//高度因子,不设置的情况,会尽可能大Widgetchild//要布局的子Widget})

       è¿™é‡Œæˆ‘们特别解释一下widthFactor和heightFactor作用:

       å› ä¸ºå­ç»„件在父组件中的对齐方式必须有一个前提,就是父组件得知道自己的范围(宽度和高度);

       å¦‚æžœwidthFactor和heightFactor不设置,那么默认Align会尽可能的大(尽可能占据自己所在的父组件);

       æˆ‘们也可以对他们进行设置,比如widthFactor设置为3,那么相对于Align的宽度是子组件跨度的3倍;

1.1.2.Align演练

       æˆ‘们简单演练一下Align:

classMyHomeBodyextendsStatelessWidget{ @overrideWidgetbuild(BuildContextcontext){ returnAlign(child:Icon(Icons.pets,size:,color:Colors.red),alignment:Alignment.bottomRight,widthFactor:3,heightFactor:3,);}}1.2.Center组件1.2.1.Center介绍

       Center组件我们在前面已经用过很多次了。

       äº‹å®žä¸ŠCenter组件继承自Align,只是将alignment设置为Alignment.center。

       æºç åˆ†æžï¼š

classCenterextendsAlign{ constCenter({ Keykey,doublewidthFactor,doubleheightFactor,Widgetchild}):super(key:key,widthFactor:widthFactor,heightFactor:heightFactor,child:child);}1.2.2.Center演练

       æˆ‘们将上面的代码Align换成Center

classMyHomeBodyextendsStatelessWidget{ @overrideWidgetbuild(BuildContextcontext){ returnCenter(child:Icon(Icons.pets,size:,color:Colors.red),widthFactor:3,heightFactor:3,);}}1.3.Padding组件1.3.1.Padding介绍

       Padding组件在其他端也是一个属性而已,但是在Flutter中是一个Widget,但是Flutter中没有Margin这样一个Widget,这是因为外边距也可以通过Padding来完成。

       Padding通常用于设置子Widget到父Widget的边距(你可以称之为是父组件的内边距或子Widget的外边距)。

       æºç åˆ†æžï¼š

constPadding({ Keykey,@requiredthis.padding,//EdgeInsetsGeometry类型(抽象类),使用EdgeInsetsWidgetchild,})1.3.2.Padding演练

       ä»£ç æ¼”练:

classMyHomeBodyextendsStatelessWidget{ @overrideWidgetbuild(BuildContextcontext){ returnPadding(padding:EdgeInsets.all(),child:Text("莫听穿林打叶声,何妨吟啸且徐行。竹杖芒鞋轻胜马,谁怕?一蓑烟雨任平生。",style:TextStyle(color:Colors.redAccent,fontSize:),),);}}1.4.Container组件

       Container组件类似于其他Android中的View,iOS中的UIView。

       å¦‚果你需要一个视图,有一个背景颜色、图像、有固定的尺寸、需要一个边框、圆角等效果,那么就可以使用Container组件。

.1.Container介绍

       Container在开发中被使用的频率是非常高的,特别是我们经常会将其作为容器组件。

       ä¸‹é¢æˆ‘们来看一下Container有哪些属性:

Container({ this.alignment,this.padding,//容器内补白,属于decoration的装饰范围Colorcolor,//背景色Decorationdecoration,//背景装饰DecorationforegroundDecoration,//前景装饰doublewidth,//容器的宽度doubleheight,//容器的高度BoxConstraintsconstraints,//容器大小的限制条件this.margin,//容器外补白,不属于decoration的装饰范围this.transform,//变换this.child,})

       å¤§å¤šæ•°å±žæ€§åœ¨ä»‹ç»å…¶å®ƒå®¹å™¨æ—¶éƒ½å·²ç»ä»‹ç»è¿‡äº†ï¼Œä¸å†èµ˜è¿°ï¼Œä½†æœ‰ä¸¤ç‚¹éœ€è¦è¯´æ˜Žï¼š

       å®¹å™¨çš„大小可以通过width、height属性来指定,也可以通过constraints来指定,如果同时存在时,width、height优先。实际上Container内部会根据width、height来生成一个constraints;

       color和decoration是互斥的,实际上,当指定color时,Container内会自动创建一个decoration;

       decoration属性稍后我们详细学习;

1.4.2.Container演练

       ç®€å•è¿›è¡Œä¸€ä¸ªæ¼”示:

classMyHomeBodyextendsStatelessWidget{ @overrideWidgetbuild(BuildContextcontext){ returnCenter(child:Container(color:Color.fromRGBO(3,3,,.5),width:,height:,child:Icon(Icons.pets,size:,color:Colors.white),),);}}1.4.3.BoxDecoration

       Container有一个非常重要的属性decoration:

       ä»–对应的类型是Decoration类型,但是它是一个抽象类。

       åœ¨å¼€å‘中,我们经常使用它的实现类BoxDecoration来进行实例化。

       BoxDecoration常见属性:

constBoxDecoration({ this.color,//颜色,会和Container中的color属性冲突this.image,//背景图片this.border,//边框,对应类型是Border类型,里面每一个边框使用BorderSidethis.borderRadius,//圆角效果this.boxShadow,//阴影效果this.gradient,//渐变效果this.backgroundBlendMode,//背景混合this.shape=BoxShape.rectangle,//形变})

       éƒ¨åˆ†æ•ˆæžœæ¼”示:

classMyHomeBodyextendsStatelessWidget{ @overrideWidgetbuild(BuildContextcontext){ returnCenter(child:Container(//color:Color.fromRGBO(3,3,,.5),width:,height:,child:Icon(Icons.pets,size:,color:Colors.white),decoration:BoxDecoration(color:Colors.amber,//背景颜色border:Border.all(color:Colors.redAccent,width:3,style:BorderStyle.solid),//这里也可以使用Border.all统一设置//top:BorderSide(//color:Colors.redAccent,//width:3,//style:BorderStyle.solid//),borderRadius:BorderRadius.circular(),//这里也可以使用.only分别设置boxShadow:[BoxShadow(offset:Offset(5,5),color:Colors.purple,blurRadius:5)],//shape:BoxShape.circle,//会和borderRadius冲突gradient:LinearGradient(colors:[Colors.green,Colors.red])),),);}}1.4.4.实现圆角图像

       ä¸Šä¸€ä¸ªç« èŠ‚我们提到可以通过Container+BoxDecoration来实现圆角图像。

       å®žçŽ°ä»£ç å¦‚下:

classMyHomeBodyextendsStatelessWidget{ @overrideWidgetbuild(BuildContextcontext){ returnAlign(child:Icon(Icons.pets,size:,color:Colors.red),alignment:Alignment.bottomRight,widthFactor:3,heightFactor:3,);}}0二.多子布局组件

       åœ¨å¼€å‘中,我们经常需要将多个Widget放在一起进行布局,比如水平方向、垂直方向排列,甚至有时候需要他们进行层叠,比如图片上面放一段文字等;

       è¿™ä¸ªæ—¶å€™æˆ‘们需要使用多子布局组件(Multi-childlayoutwidgets)。

       æ¯”较常用的多子布局组件是Row、Column、Stack,我们来学习一下他们的使用。

2.1.Flex组件

       äº‹å®žä¸Šï¼Œæˆ‘们即将学习的Row组件和Column组件都继承自Flex组件。

       Flex组件和Row、Column属性主要的区别就是多一个direction。

       å½“direction的值为Axis.horizontal的时候,则是Row。

       å½“direction的值为Axis.vertical的时候,则是Column。

       åœ¨å­¦ä¹ Row和Column之前,我们先学习主轴和交叉轴的概念。

       å› ä¸ºRow是一行排布,Column是一列排布,那么它们都存在两个方向,并且两个Widget排列的方向应该是对立的。

       å®ƒä»¬ä¹‹ä¸­éƒ½æœ‰ä¸»è½´ï¼ˆMainAxis)和交叉轴(CrossAxis)的概念:

       å¯¹äºŽRow来说,主轴(MainAxis)和交叉轴(CrossAxis)分别是下图

       å¯¹äºŽColumn来说,主轴(MainAxis)和交叉轴(CrossAxis)分别是下图

2.1.Row组件2.1.1.Row介绍

       Row组件用于将所有的子Widget排成一行,实际上这种布局应该是借鉴于Web的Flex布局。

       å¦‚果熟悉Flex布局,会发现非常简单。

       ä»Žæºç ä¸­æŸ¥çœ‹Row的属性:

classMyHomeBodyextendsStatelessWidget{ @overrideWidgetbuild(BuildContextcontext){ returnAlign(child:Icon(Icons.pets,size:,color:Colors.red),alignment:Alignment.bottomRight,widthFactor:3,heightFactor:3,);}}1

       mainAxisSize:

       è¡¨ç¤ºRow在主轴(æ°´å¹³)方向占用的空间,默认是MainAxisSize.max,表示尽可能多的占用水平方向的空间,此时无论子widgets实际占用多少水平空间,Row的宽度始终等于水平方向的最大宽度

       è€ŒMainAxisSize.min表示尽可能少的占用水平空间,当子widgets没有占满水平剩余空间,则Row的实际宽度等于所有子widgets占用的的水平空间;

       mainAxisAlignment:表示子Widgets在Row所占用的水平空间内对齐方式

       å¦‚æžœmainAxisSize值为MainAxisSize.min,则此属性无意义,因为子widgets的宽度等于Row的宽度

       åªæœ‰å½“mainAxisSize的值为MainAxisSize.max时,此属性才有意义

       MainAxisAlignment.start表示沿textDirection的初始方向对齐,

       å¦‚textDirection取值为TextDirection.ltr时,则MainAxisAlignment.start表示左对齐,textDirection取值为TextDirection.rtl时表示从右对齐。

       è€ŒMainAxisAlignment.end和MainAxisAlignment.start正好相反;

       MainAxisAlignment.center表示居中对齐。

       crossAxisAlignment:表示子Widgets在纵轴方向的对齐方式

       Row的高度等于子Widgets中最高的子元素高度

       å®ƒçš„取值和MainAxisAlignment一样(包含start、end、center三个值)

       ä¸åŒçš„是crossAxisAlignment的参考系是verticalDirection,即verticalDirection值为VerticalDirection.down时crossAxisAlignment.start指顶部对齐,verticalDirection值为VerticalDirection.up时,crossAxisAlignment.start指底部对齐;而crossAxisAlignment.end和crossAxisAlignment.start正好相反;

2.1.2.Row演练

       æˆ‘们来对部分属性进行简单的代码演练,其他一些属性大家自己学习一下

classMyHomeBodyextendsStatelessWidget{ @overrideWidgetbuild(BuildContextcontext){ returnAlign(child:Icon(Icons.pets,size:,color:Colors.red),alignment:Alignment.bottomRight,widthFactor:3,heightFactor:3,);}}.1.3.mainAxisSize

       é»˜è®¤æƒ…况下,Row会尽可能占据多的宽度,让子Widget在其中进行排布,这是因为mainAxisSize属性默认值是MainAxisSize.max。

       æˆ‘们来看一下,如果这个值被修改为MainAxisSize.max会什么变化:

2.1.4.TextBaseline

       å…³äºŽTextBaseline的取值解析

2.1.5.Expanded

       å¦‚果我们希望红色和黄色的ContainerWidget不要设置固定的宽度,而是占据剩余的部分,这个时候应该如何处理呢?

       è¿™ä¸ªæ—¶å€™æˆ‘们可以使用Expanded来包裹ContainerWidget,并且将它的宽度不设置值;

       flex属性,弹性系数,Row会根据两个Expanded的弹性系数来决定它们占据剩下空间的比例

classMyHomeBodyextendsStatelessWidget{ @overrideWidgetbuild(BuildContextcontext){ returnAlign(child:Icon(Icons.pets,size:,color:Colors.red),alignment:Alignment.bottomRight,widthFactor:3,heightFactor:3,);}}.2.Column组件

       Column组件用于将所有的子Widget排成一列,学会了前面的Row后,Column只是和row的方向不同而已。

2.2.1.Column介绍

       æˆ‘们直接看它的源码:我们发现和Row属性是一致的,不再解释

classMyHomeBodyextendsStatelessWidget{ @overrideWidgetbuild(BuildContextcontext){ returnAlign(child:Icon(Icons.pets,size:,color:Colors.red),alignment:Alignment.bottomRight,widthFactor:3,heightFactor:3,);}}.2.2.Column演练

       æˆ‘们直接将Row的代码中Row改为Column,查看代码运行效果

classMyHomeBodyextendsStatelessWidget{ @overrideWidgetbuild(BuildContextcontext){ returnAlign(child:Icon(Icons.pets,size:,color:Colors.red),alignment:Alignment.bottomRight,widthFactor:3,heightFactor:3,);}}.3.Stack组件

       åœ¨å¼€å‘中,我们多个组件很有可能需要重叠显示,比如在一张图片上显示文字或者一个按钮等。

       åœ¨Android中可以使用Frame来实现,在Web端可以使用绝对定位,在Flutter中我们需要使用层叠布局Stack。

2.3.1.Stack介绍

       æˆ‘们还是通过源码来看一下Stack有哪些属性:

classMyHomeBodyextendsStatelessWidget{ @overrideWidgetbuild(BuildContextcontext){ returnAlign(child:Icon(Icons.pets,size:,color:Colors.red),alignment:Alignment.bottomRight,widthFactor:3,heightFactor:3,);}}6

       å‚æ•°j解析:

       alignment:此参数决定如何去对齐没有定位(没有使用Positioned)或部分定位的子widget。所谓部分定位,在这里特指没有在某一个轴上定位:left、right为横轴,top、bottom为纵轴,只要包含某个轴上的一个定位属性就算在该轴上有定位。

       textDirection:和Row、Wrap的textDirection功能一样,都用于决定alignment对齐的参考系即:textDirection的值为TextDirection.ltr,则alignment的start代表左,end代表右;textDirection的值为TextDirection.rtl,则alignment的start代表右,end代表左。

       fit:此参数用于决定没有定位的子widget如何去适应Stack的大小。StackFit.loose表示使用子widget的大小,StackFit.expand表示扩伸到Stack的大小。

       overflow:此属性决定如何显示超出Stack显示空间的子widget,值为Overflow.clip时,超出部分会被剪裁(隐藏),值为Overflow.visible时则不会。

2.3.2.Stack演练

       Stack会经常和Positioned一起来使用,Positioned可以决定组件在Stack中的位置,用于实现类似于Web中的绝对定位效果。

       ä¸€ä¸ªç®€å•çš„演练:

       æ³¨æ„ï¼šPositioned组件只能在Stack中使用。

classMyHomeBodyextendsStatelessWidget{ @overrideWidgetbuild(BuildContextcontext){ returnAlign(child:Icon(Icons.pets,size:,color:Colors.red),alignment:Alignment.bottomRight,widthFactor:3,heightFactor:3,);}}7

       \

原文:/post/

没写过复杂 React 组件?来实现下 AntD 的 Space 组件吧

       React 开发者在日常工作中经常编写组件,但这些大多为业务组件,复杂度并不高。

       组件通常通过传入 props 并使用 hooks 组织逻辑来渲染视图,偶尔会用到 context 跨层传递数据。

       相对复杂的组件是怎样的呢?antd 组件库中就有许多。

       今天,我们将实现antd组件库中的一个组件——Space组件。

       首先,我们来了解一下Space组件的使用方法:

       Space是一个布局组件,用于设置组件的间距,还可以设置多个组件的对齐方式。

       例如,我们可以使用Space组件来包裹三个盒子,设置方向为水平,渲染结果如下:

       当然,我们也可以设置为垂直:

       水平和垂直的间距可以通过size属性设置,如large、middle、small或任意数值。

       多个子节点可以设置对齐方式,如start、end、center或baseline。

       此外,当子节点过多时,可以设置换行。

       Space组件还可以单独设置行列的间距。

       最后,它还可以设置split分割线部分。

       此外,你也可以不直接设置size,而是通过ConfigProvider修改context中的默认值。

       Space组件会读取context中的size值,这样如果有多个Space组件,就不需要每个都设置,只需要添加一个ConfigProvider即可。

       这就是Space组件的全部用法,简单回顾一下几个参数和用法:

       Space组件的使用方法很简单,但功能非常强大。

       接下来,我们来探讨一下这样的布局组件是如何实现的。

       首先,我们来看一下它最终的DOM结构:

       每个box都包裹了一层div,并设置了ant-space-item类。

       split部分包裹了一层span,并设置了ant-space-item-split类。

       最外层包裹了一层div,并设置了ant-space类。

       这些看起来很简单,但实现起来却有很多细节。

       下面我们来写一下Space组件的实现代码:

       首先,我们声明组件props的类型。

       需要注意的是,style是React.CSSProperties类型,即可以设置各种CSS样式。

       split是React.ReactNode类型,即可以传入jsx。

       其余参数的类型根据其取值而定。

       Space组件会对所有子组件包裹一层div,因此需要遍历传入的children并做出修改。

       props传入的children需要转换为数组,可以使用React.Children.toArray方法。

       虽然children已经是数组了,但为什么还要使用React.Children.toArray转换一下呢?

       因为toArray可以对children进行扁平化处理。

       更重要的是,直接调用children.sort()会报错,而toArray之后就不会了。

       因此,我们会使用React.Children.forEach、React.Children.map等方法操作children,而不是直接操作。

       但这里我们有一些特殊的需求,比如空节点不过滤掉,依然保留。

       因此,我们使用React.Children.forEach自己实现toArray:

       这部分比较容易理解,就是使用React.Children.forEach遍历jsx节点,对每个节点进行判断,如果是数组或fragment就递归处理,否则push到数组中。

       保不保留空节点可以根据keepEmpty的option来控制。

       这样,children就可以遍历渲染item了,这部分是这样的:

       我们单独封装了一个Item组件。

       然后,我们遍历childNodes并渲染这个Item组件。

       最后,我们将所有的Item组件放在最外层的div中:

       这样就可以分别控制整体布局和Item布局了。

       具体的布局还是通过className和样式来实现的:

       className通过props计算而来,使用了classnames包,这是react生态中常用的包,根据props动态生成className基本都会使用这个包。

       这个前缀是动态获取的,最终就是ant-space的前缀。

       这些class的样式都定义好了:

       整个容器使用inline-flex,然后根据不同的参数设置align-items和flex-direction的值。

       最后一个direction的css可能大家没用过,是设置文本方向的。

       这样,就通过props动态给最外层div添加了相应的className,设置了对应的样式。

       但还有一部分样式没有设置,也就是间距。

       其实这部分可以使用gap设置,当然,也可以使用margin,但处理起来比较麻烦。

       不过,antd这种组件自然要做得兼容性好一点,所以两种都支持,支持gap就使用gap,否则使用margin。

       问题来了,antd是如何检测浏览器是否支持gap样式的呢?

       antd创建一个div,设置样式,并添加到body下,然后查看scrollHeight的值,最后删除这个元素。

       这样就可以判断是否支持gap、column等样式,因为不支持的话高度会是0。

       然后antd提供了一个这样的hook:

       第一次会检测并设置state的值,之后直接返回这个检测结果。

       这样组件里就可以使用这个hook来判断是否支持gap,从而设置不同的样式了。

       最后,这个组件还会从ConfigProvider中取值,我们之前见过:

       所以,我们再处理一下这部分:

       使用useContext读取context中的值,并设置为props的解构默认值,这样如果传入了props.size就使用传入的值,否则使用context中的值。

       这里给Item子组件传递数据也是通过context,因为Item组件不一定会在哪一层。

       使用createContext创建context对象:

       把计算出的size和其他一些值通过Provider设置到spaceContext中:

       这样子组件就能拿到spaceContext中的值了。

       这里使用了useMemo,很多同学不会用,其实很容易理解:

       props变化会触发组件重新渲染,但有时候props并不需要变化却每次都变,这样就可以通过useMemo来避免它不必要的更新。

       useCallback也是同样的道理。

       计算size时封装了一个getNumberSize方法,为字符串枚举值设置了一些固定的数值:

       至此,这个组件我们就完成了,当然,Item组件还没展开讲。

       先来欣赏一下这个Space组件的全部源码:

       回顾一下要点:

       思路理得差不多了,再来看一下Item的实现:

       这部分比较简单,直接上全部代码了:

       通过useContext从SpaceContext中取出Space组件里设置的值。

       根据是否支持gap来分别使用gap或margin、padding的样式来设置间距。

       每个元素都用div包裹一下,设置className。

       如果不是最后一个元素并且有split部分,就渲染split部分,用span包裹。

       这块还是比较清晰的。

       最后,还有ConfigProvider的部分没有看:

       这部分就是创建一个context,并初始化一些值:

       有没有感觉antd里用context简直太多了!

       确实。

       为什么?

       因为你不能保证组件和子组件隔着几层。

       比如Form和FormItem:

       比如ConfigProvider和各种组件(这里是Space):

       还有刚讲过的Space和Item。

       它们能用props传数据吗?

       不能,因为不知道隔几层。

       所以antd里基本都是用context传数据的。

       你会你在antd里会见到大量的用createContext创建context,通过Provider修改context值,通过Consumer或useContext读取context值的这类逻辑。

       最后,我们来测试一下自己实现的这个Space组件吧:

       测试代码如下:

       这部分不用解释了。就是ConfigProvider包裹了两个Space组件,这两个Space组件没有设置size值。

       设置了direction、align、split、wrap等参数。

       渲染结果是正确的:

       就这样,我们自己实现了antd的Space组件!

       完整代码在github:github.com/QuarkGluonPl...

       总结:

       一直写业务代码,可能很少写一些复杂的组件,而antd里就有很多复杂组件,我们挑Space组件来写了下。

       这是一个布局组件,可以通过参数设置水平、垂直间距、对齐方式、分割线部分等。

       实现这个组件的时候,我们用到了很多东西:

       很多同学不会封装布局组件,其实就是对整体和每个item都包裹一层,分别设置不同的class,实现不同的间距等的设置。

       想一下,这些东西以后写业务组件是不是也可以用上呢?

copyright © 2016 powered by 皮皮网   sitemap