1.mui Դ?码分????
2.畅谈React material-ui的样式方案
mui Դ?????
/question/.html?istorch=1&torchtoken=beyHTXGvXMlReCeEI3oyMtJ6a4e+htHlsAS1WBnogSWf+aa+4q4XbB3MGioxEzt//HCJPCdGVPF5hVerayjCHt/5QDThg5lOEXPzhmUi
畅谈React material-ui的样式方案
Google 在 年提出了 material design 的设计理念,极具颠覆性,码分在国外非常受欢迎。码分各类前端框架也都出现了material design风格的码分组件库,其中 React 最受欢迎的码分 material design 风格组件库非 material-ui 莫属。mui-org/material-ui 这个开源库目前收获了 star,码分看板的源码npm 的码分周下载量达到了 万,数据摆在那儿,码分也不需要继续“吹捧” material-ui 了。码分本文主要是码分带大家一起领略一下 material-ui 的样式方案。
material-ui 将自己的码分样式方案独立发布成一个 npm 包,叫 @material-ui/styles。码分它拥抱了CSS-in-JS,码分据他们的码分文档,也尝试过使用 LESS 等其他方案,码分但发现有明显的局限性,最后拥抱了 CSS-in-JS。官方文档宣称material-ui 样式方案有以下优点。
使用 @material-ui/styles 的jedis源码解析样式方案主要支持三种形式的API,但底层的代码和逻辑是一致的。下面是代码示范,通过 makeStyles API,传入一个描述CSS的对象(下面简称css对象),就能得到一个自定义的Hook,通常命名为 useStyles。在函数式组件内调用这个Hook,得到一个对象,通常命名为classes。新兴源码网最后,将classes 对象的“对应值” 赋给 组件的 className 属性,就成功定制了这个组件的样式。细节:classes对象的 root 属性 对应的就是 css对象的 root 属性。下面是代码示范:
使用 styled API 就能采用类似于 styled-components 的语法,当然还是有区别的 —— styled-components 用的是 es6 tagged template literals 而 material-ui styled API 返回函数的参数是css对象。使用 Higher-order component API 接收一个 css 对象返回一个高阶组件函数。material-ui 的 Higher-order component API 不仅能用于函数组件也能用于类组件,但在 Hook 大行其道后这个 API 慢慢退出舞台了。燕窝 溯源码接下来都只使用 makeStyles API 做后面的代码示范。
material-ui 上述的API 在底层都会生成一些“随机的html class 名称” 以及 相应的 css 规则。以 上面的 makeStyles demo 为例,会生成以下 css 规则插入到 html head。自定义样式按钮 对应的 html 片段如下。小结:上述这三种形式的API都能定制化组件的样式。查看源码就能发现其实 styled 和 withStyles 底层都调用了makeStyles API。
在底层原理是动态生成 css 规则插入到 html 中。这三个API的源码编辑教程使用方法中,最关键的都是两部分:查看 css 对象的构成和使用。接下来将细聊 css 对象的构成和使用。嵌套选择器:上面的代码可以得到以下效果。实际生成的 css 规则如下。
根据传入值动态调整:上述的 css 对象并不一定是单纯的简单对象。可以将函数传递给makeStyles (“插值”),这样一来根据组件的属性可以变换生成的样式的值。 此函数可以运用于样式规则的级别,也可以放在 CSS 属性级别。例1和例2展示了如何根据组件属性动态调整样式。
覆盖样式 —— classes 属性:接下来换个角度,假如你使用 material-ui 样式方案创作了一些组件(提供了默认的样式)并作为公用组件分享给其他模块使用,如何让调用端可自定义这些组件的样式呢?上面提到的根据传入值动态调整 是一种解决方案,但很明显这是一种只允许微调的方案;而且这个方案的实现通常比较繁琐。假如以下是我们设计的一个组件代码。那么我在 Parent 中如何自定义这个 Nested 组件的 span 样式呢?我们可以利用classes属性 覆盖样式。上面的代码中,我们往 useStyles 这个hook中传入 props 作为参数 (其实是为了将 classes 传进去)。而在 Parent 的代码中,我们给 Nested 传入 classes 属性(这个命名是个规范,必须遵守)。最终的效果生成的 html 中 span 的 class 值是 ‘makeStyles-label-2 my-label’ —— 注意 my-label 的顺序在后面,因此它的样式会覆盖前面 makeStyles-label-2 的样式。
总结:你所在前端项目使用的样式方案还是 LESS, SASS 甚至是 css 吗?material-ui 样式解决方案是不是对你有所冲击或者启示呢?欢迎留言评论。如果觉得文章质量不错,请积极地点赞、喜欢、收藏三连!p.s. material-ui 样式方案中还有其他内容,如主题、JSS 插件等,个人感觉难度比较小,文档也易懂,(或者过于生僻,很少使用),本文就不做介绍了,如果有读者强烈要求写某个部分,我再继续补充。