css-modules的理解及在vue/react框架下的实践

目录

为什么引入css-modules概念

什么是css-modules

css-modules核心特点

        作用域:

        命名:

        组合:

        变量:

有哪些工具可以支持css modules的几个特点 / 如何使用?

在vue中如何编写来实现css局部作用域的?

1:scope css 

2:开启 css modules模块化处理

在react中如何编写来实现css局部作用域的?

        先说下如果不介入插件,react中如何实现样式写法:

        1:css-modules类型

        2:css-in-js类型

        对比css-in-js与css modules有什么不一样:

参考文档:


为什么引入css-modules概念

        前端网页样式开发经常会遇到一些问题,类名命名很头疼,类名重复,样式污染被覆盖,样式嵌套层级过深;那css可不可以像js一样,即可以拥有自己的作用域(防止全局样式污染,命名重复),同时也可以将复用的样式进行封装,组合,嵌套(防止嵌套层级过深)。css-modules这个概念就应运而生了。

什么是css-modules

        css-modules  不是一种语言,也不是一个规范。它是一种将css利用模块化的思维来管理样式的一种 理念。那这种理念都有什么特点?

css-modules核心特点

作用域:

        模块中的类名 默认是本地局部作用域,用:global(类名)是全局作用域。本地作用域下的类名 会按照一定规则 被编译成携带hash值 的全局唯一类名。全局作用域下的类名将保留原始写法不会被编译;

 命名:

        建议使用className小驼峰形式定义类型,在组件中会通过访问对象中键的方式来引用类名,小驼峰命名利于打点访问。

组合:

        不同类名如何复用组合实现更复杂的样式? composes:需要复用的类名  即可实现

变量:

        变量的定义和使用,

        @value  变量名:变量值  定义变量 ;

        @value 变量名 from '定义变量的文件'    css属性名:引进来的变量名   

有哪些工具可以支持css modules的几个特点 / 如何使用?

一般在工程中需要将几个工具加一起使用:

  •         postcss-loader:支持样式变量功能,处理变量转为css
  •         css-loader:模块化导入导出引用,作用域;处理模块导入导出,转化为css
  •         style-loader:将css添加到指定dom中,实现浏览器可渲染写法
  •         (当然你也可以引入 less-loader,sass-loader之类的预处理来实现更高级的写法)

        

具体的代码demo实现,请移步代码仓  GitHub - zhangpanjun/css-modules-demos: react框架下实现css-modules的一些demo

  • demo1:基础用法,实现组件作用域。
  • demo2:全局作用域,组件作用域的区别。
  • demo3:自定义组件作用域生成出来的样式规则。
  • demo4:文件内样式引用组合
  • demo5:跨文件样式引用组合
  • demo6:叠加 postcss-loader来实现变量的定义及引用使用

在vue中如何编写来实现css局部作用域的?

1:scope css 

这种方式是大家最常见的方式,在style标签上标记 scoped,vue底层会将当前组件中应用到的类名的对应元素上都打上一个'data-v-hash值'的属性,类名+属性选择器 打包一起作为这个元素的样式选择器。hash值是唯一的,就算类名相同,组合后的也是不相同。

编译后的样式渲染表现:

2:开启 css modules模块化处理

      在style标签上开启 module,在需要使用类名的地方通过:class=''$style.类名''动态绑定样式

编译出来的效果,类名被渲染为  组件名_类名_hash

原理:vue在内部处理了 style标签上有module标识,即开启了css modules的方式来渲染类型。

        $style是vue为每个组件内置注入的一个计算属性,当对象的值变化就会响应式渲染在页面上。

对于全局应用的样式怎么处理呢,除了常见的:global(类名){属性:值},你还可以放一个style标签专门写全局样式

那不用内置的$style用自定义的名字是否可以?当然,在module这里附上你起得别名就可使用了

使用scope css在写class="类名"没有提示,带来不便,使用css modules可以根据对象中的属性推荐,可大大提高开发效率。

那对于会变化的属性值,除了常见的内联style的值作为参数条件渲染,或者起多个类名来条件渲染,还可以使用v-bind('变量名')来实现;通过这种方式,会将最新的值以内联的方式应用到元素上。

在react中如何编写来实现css局部作用域的?

react没有像vue框架有内置的关于局部作用域的相关处理,react框架更纯粹,只是一个用于构建用户界面的 JavaScript 库。要想实现css局部作用域就要借助一些插件。再配合上一些loader(style-loader,css-loader,babel-loader等)进行转化后,才可实现。

先说下如果不介入插件,react中如何实现样式写法:

        如下图所示,react本身保留了对于style的属性内联实现传入样式。解析也是内联样式来进行渲染。

插件的话,大体有2个方向:

1:css-modules类型

         在项目中引入实现css modules特性的一些插件(css-loader,postcss-loader)等,大概需要3个loader来共同实现 css modules的 局部作用域,模块化导入导出相互引用,样式变量。

具体请异步代码仓 GitHub - zhangpanjun/css-modules-demos: react框架下实现css-modules的一些demo

2:css-in-js类型

        和react的一个显著特点jsx(用/在js中写dom)语法理解类似, css-in-js 可以理解为用/在js中写css样式。

        那怎么写?不同插件实现方式不容,但基本上其实和上面不引用任何插件的思想一致。以其中一个插件 polished.js 为例:

        首先,加载 polished.js

const polished = require('polished');

        增加清除浮动效果

const styles = {
  ...polished.clearFix(),
};
const styles2 = {
  ...polished.ellipsis('200px')
};
ReactDOM.render(
  <div>
    <h1 style={styles}>Hello, React!</h1>
    <div style={styles2}>内容省略号</div>
   </div>,
  document.getElementById('example')
);

      那上面的 styles返回的是个什么?大家一看大概也能猜出来,是一个包含清除浮动的一个对象

// {
//  &::after: {
//    clear: "both",
//    content: "",
//    display: "table"
//  }
// }

        要是想要再增加别的样式呢?那就看 polished.js 插件提供的api,展开运算符接着叠加即可。当然也可以自己手写进去。

      对比css-in-js与css modules有什么不一样:

        css-in-js:

                不同插件可能写法不一样,但都是js写法,无需额外学习;

                样式代码也放在js中,对于组件化来讲聚合度更高,无需关注外部有什么依赖。更关注组件内部的功能实现。组件复用性更高。

                因为在js中编写可以很好融入变量,对于动态功能复杂的ui,是理想解决方案;

                这种写法不符合‘关注点分离’的理念,为项目增加了一定的复杂度。

      css-modules:

              符合 ‘关注点分离’的理念,代码阅读性更高;

               使用它需要有额外的loader进行配置来支撑,预处理css的less,sass需要有额外的学习成本;   

参考文档:

https://cn.vuejs.org/api/sfc-css-features.html#css-modules

GitHub - css-modules/css-modules: Documentation about css-modules

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值