在公司項目中,咱們一直class名稱遵循bem規範,可是在使用中,也發現了一些不方便的地方javascript
ns-dialog__title--center
爲了簡化bem規範的使用複雜度,我借鑑了幾個框架的方法,打造了一款比較簡單易用的插件庫css-bem
(github.com/snowzijun/c…)。css
在這個插件庫中,爲了更符合經常使用的組件庫樣式的命名,在bem規範基礎上,我又新增了一個命名空間(namespace)概念,變成了nbem,如京東taro-ui框架輸入框的樣式at-input__overlay--hidden
,at
爲namespace
,input
爲block
,overlay
爲element
,hidden
爲modifier
vue
npm install css-bem
import cssBem from 'css-bem'
複製代碼
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>
複製代碼
// 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
複製代碼
// 使用裝飾器
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)
複製代碼
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' */
複製代碼