浅谈 Antd 中的布局模式
Posted VTime
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅谈 Antd 中的布局模式相关的知识,希望对你有一定的参考价值。
Antd 框架是一个服务于企业级产品的设计体系,基于“确定”和“自然”的设计价值观和模块化的解决方案,让设计者专注于更好的用户体验,它是 Ant Design 设计规范的React 实现。我行基于原生的 Antd 框架对其进行了客制化封装,推出了自己的 bocomUI 框架,用以配合React 框架进行响应式(Responsive)前端开发。
在实际开发工作中接触到全新 Antd 框架一段时间后,我在使用和研究中积累了一些经验, 也对 Antd 的布局模式及部分组件的使用有了一些自己的理解,希望能够借由此篇文章分享开来,为大家提供一个思路。
网页界面设计的布局模式(Layout)简称布局(下同),是一种基于 html 中的基本元素“块级元素”(Block Element)和其他“块级元素”的交互方式来确定每个“块级元素”在展示给用户的图形化界面上的位置(Position)和大小(Size)的算法。
对于“块级元素”,我将其理解为一个一个的长方形盒子;对于展示给用户的界面,我将其理解为一张画布。由此,布局实际上是一项将若干个不同的盒子,通过调整其大小,位置及重叠关系,让这些盒子在画布上排列出既便于观看者理解,又不缺乏美感的画面的活动。
那么,当我将对布局的理解引申到网页界面设计上来时,这些画面上的盒子可能包含了一个输入框(Input),一个按钮(Button),或者是一个展示数据用的表格(Table)。作为开发者,也就是手拿画笔的画家,我需要在理解用户想要看到什么样的画面的基础上,对这些盒子以功能为基础进行组合(Grouping)、伸缩(Telescopic)、嵌套(Nesting),并以让用户看起来简洁明了为目标对盒子们进行画布定位,完成作画。
在数以百计、千计的重复作画后,依据用户对不同作画结果的反馈(User Experience),开发者们通过归纳与总结(User Experience Testing),得出了若干套行之有效的对盒子们进行布局的模式,通过套用不同的模式,开发者能够快速完成面向不同用户需求的界面布局工作, 这就是我所理解的布局模式。
Antd 中的布局模式
Antd 提供了一整套用于布局的组件给开发者使用,我们可以通过调用 Antd 提供的不同组件对盒子进行包装、排列,借用简单的参数设置让盒子变成我们需要的形状,出现在我们需要的位置。
在 Antd 中,布局的基本元素是栅格(Grid),它由两个标签组成:Row 和Col。
Row 规定了一个条形盒子,Col 将这个盒子从左至右等分成 24 份,所有居于这个条形盒子中的其他盒子都会默认向左对齐,这就是 Antd 的 24 栅格布局模式(24-Grid Layout)。
在这个模式中,我们通过指定在某一条 Row 中,一个盒子占用多少个 Col 来规定盒子的宽度(Width),通过在盒子中包含其他组件来让盒子的高度(Height)动态变化。同时这个盒子会自动向左对齐,既左侧边框所在的位置为 Col=0 的位置;如果是右对齐,那么就是盒子的右侧边框所在的位置为 Col=设置值 的位置。例如,我规定盒子 A 占 12 个格子,盒子 B 占 8 个格子,它们俩加起来占了 20 个格子,那么在页面上展示出来就是如图 1 所展示的样式了:
图 1 – Row-Col 占位
如图所示,由于自动左对齐的存在,盒子 B 右侧到整个 Row 的边界还留有 4 个格子的空位。
我们可以通过一个 Row 里面包含若干个其他盒子,对这些盒子通过 Col 来设置大小、位置的方式对页面进行每一行的设置。每一行的高度并不受限制,只有宽度收到控制,每个 Row 的高度是由其内部最高的盒子决定的,所以不需要担心内部的盒子太高,导致布局混乱。
那么,如何让一个 Row 内的盒子和外部的另一个盒子对齐呢?在这一点上我想提出,所有基于栅格的布局计算,必须选对参照物(Reference)。例如,盒子 A 占据了整个画布的 12个格子,那么我对盒子 A 内部的盒子 B 和盒子C 进行布局计算时,应当用谁来做参照坐标? 这里就需要加深对Col 这个标签作用方式(Effective Pattern)的理解了:Col 的计算,永远是基于当前盒子的 24 栅格坐标系来的。对于这句话,我基于自己的理解画了一个示意图:
图 2 – Col 对齐计算示意图
如图所示,要想算出FormItem 标签中 Label 和 Wrapper 一共占了Row 的多少个格子,既首先计算出 Label 和 Wrapper 占了全部 24 个格子的比例,再乘以其坐标长度的总长即可。既可以通过公式得出:
当前Col 的设定值/24 x 当前Col 所在盒子的Col 值
在此例中,我将 FormItem 当做了参照物,所以 Label 和 Wrapper 可以认为是处于由
FormItem 中的 24 个栅格所划定的坐标系中,因此当前Col 的设定值分别为:
Label:占据 FormItem 的 6 个格子
Wrapper:占据 FormItem 的 16 个格子
当前Col 所在盒子的Col 值:FormItem 占据 Row 的 12 个格子套用在我所举出的例子中,公式可变形为:
(Label 占的格子+Wrapper 占的格子)/ 24 x ForItem 所占的格子,
既:
(6 + 16)/ 24 x 12 = 11 个格子
也就是说,FormItem 标签中的 Label 和 Wrapper 两个盒子分别占据了 FormItem 这个盒子自身划分出的 24 栅格的 6 和 16 个格子,但是它们在 Row 这个盒子中,只占据了Row 这个盒子自身划分出的 24 栅格的 3 和 8 个格子。这时,基于默认的左对齐模式,我们只需要让Row 外部需要进行对齐的盒子X 占据了(12-1)个格子,同时右对齐
(style={{ textAlign = “right” }}),就能让盒子 X 的右侧边框和 Wrapper 的右侧边框对齐了。
在得出了上述结论之后,只要稍微转换一下进行布局时的思考模式(Thinking Pattern),就能很轻松的对复杂的盒子套盒子的情形进行分解处理(Decomposition Processing)了:盒子 A 里包含了盒子 B,盒子 B 包含了盒子C 和盒子D,我需要盒子C 和盒子D 各占盒子 B 一半的位置,那么只需要设定盒子C 占 12 个格子,盒子D 占 12 个格子即可,因为它们所占格子的计算,是仅以盒子 B 为参照物的,和盒子A 以及整个页面没有一点关系。而我需要盒子 A 所包含的这一组盒子位于整个页面的右侧,由于盒子内部所包含的盒子的位置完全由最外层的盒子所决定,我们只需要设置盒子A 的位置就能让这个盒子组向页面右侧对齐:设置盒子A 占 24 个格子,同时右对齐即可。
基于 Antd 开发时的一些发现
在进行实际开发布局时,我总结了一些有用到的情形,简单罗列一下:
(1) Antd 的标签可以和 HTML 的原生标签(Original Element)混用,并且互不影响。例如,我会用section 标签对页面进行分块,每一块中再放若干个Row 标签来进行布局。
(2) 在 Antd 的组件中可以对带有 HTML 标签的字符串进行 HTML 渲染(Render),例如 <List header = { <div dangerouslySetInnerHTML = {{ html: “Hello <br />
World”}} /> },通过 React 中的 dangerouslySetInnerHTML 方法,就可以把带有
HTML 标签的字符串以 HTML 格式进行渲染了
(3) Col 设置时只能用正整数(Positive-Integer Only),所以要仔细计算以防不测。
(4) 在 Form 组件中,一个 Row 内放置的输入框、下拉框(Select)类型的盒子不超过三个,可以保证显示的清楚,又不失整洁(Tidy & Clean),多了容易显得拥挤。
(5) 我在其他组件内部进行布局的基本标签顺序为:其他组件-Row-Col-格子内的文字。
(6) 让盒子向右对齐的写法:<Col span = {x} style = {{ textAlign=”right” }}>。
(7) 在做盒子之间的对齐计算时,推荐先算好每个大盒子(Bigger Block / Main
Container)的位置,再根据大盒子的位置调整内嵌小盒子(Smaller Block / Sub
Element)的位置和大小。
(8) 善用Chrome 等浏览器自带的开发者工具(Developer Tool-Kit),在浏览器中按
Ctrl+Shift+I 或 F12 打开,图中圈出来的工具在进行布局调整时有奇效,点击一次后将鼠标移至页面上,就可以选中对应的块级元素来详细查看块级元素的样式属性,便于调试和调整。
图 3 – Chrome 浏览器开发者工具
以上是关于浅谈 Antd 中的布局模式的主要内容,如果未能解决你的问题,请参考以下文章