写点什么

记一次 bem 命名规范使用优化方案

发布于: 2020 年 07 月 22 日
记一次bem命名规范使用优化方案

背景

在公司项目中,我们一直class名称遵循bem规范,但是在使用中,也发现了一些不方便的地方

  • class名称比较长,写起来比较麻烦,一个dialog文字位置的样式需要写成ns-dialog__title--center

  • 在使用多个class时候需要拼字符串,特别是如果存在条件判断的样式,还需要进行if判断 下图是蚂蚁金服 ant design 框架的一段样式处理,虽然进行了包装处理,但是还是稍显麻烦



解决方案

为了简化bem规范的使用复杂度,我借鉴了几个框架的方法,打造了一款比较简单易用的插件库css-bem(https://github.com/snowzijun/css-bem)。



在这个插件库中,为了更符合常用的组件库样式的命名,在bem规范基础上,我又新增了一个命名空间(namespace)概念,变成了nbem,如京东taro-ui框架输入框的样式at-input__overlay--hidden,atnamespace,inputblock,overlayelement,hiddenmodifier



安装
npm install css-bem
import cssBem from 'css-bem'
基本用法(以react开发Button组件为例)
import cssBem from 'css-bem'
// 声明 namespace 与 block
const nbem = cssBem('zj','button')
// 组件
export default class Button extends React.Component{
static propTypes={
type:PropTypes.string,
plain:PropTypes.bool,
disabled: PropTypes.bool
}
render(){
const {type,plain,disabled} = this.props
return (
<button className={nbem([type,{disabled,plain}])}>
<span className={nbem('text')}>按钮文字</span>
</button>
)
}
}
// 页面
export default class Page extends React.Component{
render(){
// 设置按钮 type为primary,plain为false disabled为true
return <Button type='primary' plain={false} disabled></Button>
}
}
// 渲染结果
<button class='zj-button zj-button--primary zj-button--disabled'>
<span class='zj-button__text'>按钮文字</span>
</button>
api说明
// namespace可省略不写 如 cssBem('button')
const nbem = cssBem('zj','button')
nbem() // zj-button
nbem('text') // zj-button__text
nbem(['primary']) // zj-button zj-button--primary
nbem({disabled:true,plain:false}) // zj-button zj-button--disabled
nbem(['primary',{disabled:true}]) // zj-button zj-button--primary zj-button--disabled
nbem('text',['large',{show:true}]) // zj-button__text zj-button__text--large zj-button__text--show



React 高阶组件
// 使用装饰器
import {injectBem} from 'css-bem'
@injectBem('zj','button')
export default class Button extends React.Component{
render(){
const {type,plain,disabled} = this.props
const { classnames } = this
return <button className={classnames([type,{disabled,plain}])}>
<span className={classnames('text')}>按钮文字</span>
</button>
}
}
//使用高阶组件
class Button extends React.Component{
// 内容与装饰器一直
}
export default injectBem('zj','button')(Button)



Vue mixins
import {vueMixin} from 'css-bem'
export default{
mixins:[vueMixin('zj','button')]
}
<template>
<button :class="classnames([type,{disabled,plain}])">
<span :class="classnames('text')">按钮文字</span>
</button>
</template>



其他说明
// 不使用namespace与block
import {flatten} from 'css-bem'
flatten('header',['header__text',{
'header__icon--show':false,
'header--dark':true
}])
/**输出
'header header__text header--dark'
*/



发布于: 2020 年 07 月 22 日阅读数: 69
用户头像

技术日新月异,我愿紧随不舍 2020.07.10 加入

不要吹灭你的灵感和你的想象力; 不要成为你的模型的奴隶。

评论

发布
暂无评论
记一次bem命名规范使用优化方案