做者:凹凸曼-冥冥javascript
小程序的简化版 css-modules,比标准 css-modules 代码量更少的优化方案css
css-modules 是一种 css 模块化方案,它在构建过程当中生成一个原类名与新类名的 map,根据 map 引用样式,经过设定 hash 规则,实现了对 CSS 类名做用域的限定,它一般用来解决页面类名冲突的问题。因为微信小程序内组件样式默认隔离,为何要使用 css-modules 呢?java
有如下 2 个缘由:webpack
weapp-css-modules 作了哪些事?git
标准 css-modules 方案:github
import style from './index.wxss' <view class="{{style.banner}}"></view> .index_banner_xkpkl { xx } module.exports ={'banner' : 'index_banner_xkpkl'} // 额外生成的 map 文件
weapp-css-modules 编译后效果:web
let style = {} <view class="a"></view> .a { xx }
目前只开发了适用于使用 gulp 编译小程序的 gulp 插件,后续计划开发 webpack 可用的插件实现相同功能npm
npm i gulp-weapp-css-modules gulp-sort
// gulpfile.js const { weappCssModule, wcmSortFn } = require('gulp-weapp-css-modules') const sort = require('gulp-sort'); gulp.task('css-module', () => { return gulp.src('./src/**/*') .pipe(sort(wcmSortFn)) // 因为处理文件有顺序依赖,须要先对文件排序 .pipe(weappCssModule()) .pipe(gulp.dest('./dist')) })
小程序页面不具有隔离功能,所以只有具有样式隔离的 Component 能够改造使用 weapp-css-modulesgulp
一、css 文件更名字: weapp-css-modules 经过 css 文件是否带 module 来识别须要替换的内容小程序
index.wxss
-> index.module.wxss
// 或者使用 scss/其余
index.scss
-> index.module.scss
二、js 内新增样式文件的引入,目的是创建 css-modules 的样式与 js 关系
import styles from './index.module.wxss data:{ ..., styles:styles }
三、修改 js 内类名的地方替换为 styles 的间接引入
query.select('.banner') .boundingClientRect() .exec(function (res) {...}) // 改成 query.select('.' + styles['banner']) .boundingClientRect() .exec(function (res) {...})
四、修改 wxml 内类名的使用
4.1. 普通类名
<view class="banner"></view> // 改成 <view class="{{styles.banner}}"></view> // 或者 <view class="{{styles['banner']}}"></view>
4.2. 三目运算符
<view class="banner__dot {{ 'banner__dot--' + (index == swiperCurrent ? 'cur' : '')}"></view> // 改成 <view class="{{styles['banner__dot'] + ' ' + (index == swiperCurrent ? styles['banner__dot--cur'] : '')}}"></view> // 或者 <view class="{{`${style['banner__dot']} ${index == swiperCurrent ? style['banner__dot--cur'] : ''}`}}"></view>
这里须要注意几种有问题的写法:
4.2.1. 类名间未加空格
<view class="{{styles['banner__dot'] + (index == swiperCurrent ? styles['banner__dot--cur'] : '')}}"></view>
4.2.2. 三目表达式未加括号,运算优先级不明
<view class="{{styles['banner__dot'] + ' ' + index == swiperCurrent ? styles['banner__dot--cur'] : ''}}"></view>
4.2.3. styles 的属性须要是具体的字符串,不能使用变量表达式(这是 weapp-css-modules 须要单独关注的地方,由于编译阶段会对 styles.xx 进行求值,因此不能把表达式写在属性位置)
<view class="{{styles['banner__dot'] + ' ' + styles[index == swiperCurrent ? 'banner__dot--cur': '']}}"></view>
五、构建过程当中关注脚本的红色提示,相似于这种:
这是因为在 js/wxml 内使用了一个banner__swiper_2
,而 css 内并无定义banner__swiper_2
,css-module 编译的 map 文件是根据 css 内的样式定义来生成 key 名的,所以styles['banner__swiper_2']
是undefined
, 针对这种状况有两种处理方式:
5.1. 若是 js 内须要经过这个类名选择到某个元素,可是 css 内不须要编写样式,那么能够将它视为不须要编译的类名,即:
query.selector('.banner__swiper_2') // 不改为 styles.xx 的写法 <view class="banner__swiper_2"></view> // 相应的元素也不索引到 styles // 这样实现了一个组件内不会被编译的样式
5.2. 若是 js 内无引用,那么删掉 wxml 内该类名的定义吧~
六、构建完进行检查,关注样式和交互是否正常
/demo/gulp-project-demo
欢迎关注凹凸实验室博客:aotu.io
或者关注凹凸实验室公众号(AOTULabs),不定时推送文章。