Generate programmatically BEM classes with a light-weight vue plugin.
npm install --save vue-bem-generator
import VueBemGenerator from 'vue-bem-generator';
Vue.use(VueBemGenerator);
<template>
<div :class="bem()">
<div :class="bemElem('content')">
<button :class="bemElem('button', ['primary', 'big'])">Go Next</button>
</div>
</div>
</template>
<script>
export default {
name: 'main-block',
};
</script>
// Renders
<div class="main-block">
<div class="main-block__content">
<button
class="main-block__button main-block__button--primary main-block__button--big"
>
Go Next
</button>
</div>
</div>
<template>
<div :class="bem()">
Content
</div>
</template>
<script>
export default {
name: 'main-block',
};
</script>
// Renders
<div class="main-block">
Content
</div>
If don't want to use component name, could be used block.
<template>
<div :class="bem()">
Content
</div>
</template>
<script>
export default {
name: 'main-block',
block: 'section-block'
};
</script>
// Renders
<div class="section-block">
Content
</div>
Also block and name would be overwritten with bem method.
<template>
<div :class="bem('custom-block')">
Content
</div>
</template>
<script>
export default {
name: 'main-block',
block: 'section-block'
};
</script>
// Renders
<div class="custom-block">
Content
</div>
<template>
<div :class="bem()">
<div :class="bemElem('content')">
Content
</div>
</div>
</template>
<script>
export default {
name: 'main-block',
};
</script>
// Renders
<div class="main-block">
<div class="main-block__content">
Content
</div>
</div>
Usually you don't need nested elements but it could be used by sending an array.
<template>
<div :class="bem()">
<div :class="bemElem(['content', 'subcontent'])">
Content
</div>
</div>
</template>
<script>
export default {
name: 'main-block',
};
</script>
// Renders
<div class="main-block">
<div class="main-block__content__subcontent">
Content
</div>
</div>
If you need an element with different block name use bem method instead bemElem (usually that means you need another component but I'm not going to judge you).
<template>
<div :class="bem()">
<div :class="bemElem('content')">
Content
</div>
<div :class="bem('side-block')">
Content
</div>
</div>
</template>
<script>
export default {
name: 'main-block',
};
</script>
// Renders
<div class="main-block">
<div class="main-block__content">
Content
</div>
<div class="side-block">
Content
</div>
</div>
On elements array, values can be disabled if used falsy values (to enable it again should be used string value).
<template>
<div :class="bem()">
<div :class="bemElem([content, subcontent])">
Content
</div>
</div>
</template>
<script>
export default {
name: 'main-block',
data() {
return {
content: 'content'
subcontent: false
};
}
};
</script>
// Renders
<div class="main-block">
<div class="main-block__content">
Content
</div>
</div>
String or array could be used for simple modifiers.
<template>
<div :class="bem()">
<div :class="bemElem('content')">
<button :class="bemElem('btn', 'primary')">Update</button>
<button :class="bemElem('btn', ['danger', 'big'])">Delete</button>
</div>
</div>
</template>
<script>
export default {
name: 'main-block',
};
</script>
// Renders
<div class="main-block">
<div class="main-block__content">
<button class="main-block__btn main-block__btn--primary">Update</button>
<button class="main-block__btn main-block__btn--danger main-block__btn--big">Delete</button>
</div>
</div>
Of course only modifiers could be used.
<template>
<div :class="bemMod('fullsize')">
<div :class="bemElem('head')">
Head
</div>
</div>
</template>
<script>
export default {
name: 'dialog',
};
</script>
// Renders
<div class="dialog dialog--fullsize">
<div class="dialog__head">
Head
</div>
</div>
In same way like elements, a falsy value can disable a modifier.
<template>
<div :class="bemMod([color, bordered])">
Content
</div>
</template>
<script>
export default {
name: 'main-block',
data() {
return {
color: 'green',
bordered: false // Remember to use a string for enable this
};
}
};
</script>
// Renders
<div class="main-block main-block-green">
Content
</div>
Instead sending string or array for modifiers, send an object allowing you to use hyphenate notation.
<template>
<div :class="bemMod({size: 'fullsize', type: 'confirm'})">
<div :class="bemElem('head')">
Head
</div>
</div>
</template>
<script>
export default {
name: 'dialog',
};
</script>
// Renders
<div class="dialog dialog--size-fullsize dialog--type-confirm">
<div class="dialog__head">
Head
</div>
</div>
Instead of string on each object element, boolean values can disable/enable them.
<template>
<ul :class="bem()">
<li
v-for="(item, i) in items"
:key="i"
:class="bemElem('item', { selected: item.selected })"
>
{{ item.value }}
</li>
</ul>
</template>
<script>
export default {
name: 'list',
data() {
return {
items: [
{ value: 'One task', selected: false },
{ value: 'Other task', selected: true }
]
};
}
};
</script>
// Renders
<ul class="list">
<li class="list__item">One task</li>
<li class="list__item list__item--selected">Other task</li>
</ult>
Defines BEM class with all 3 optional parameters. If no one is sent, block name is set with block or name component value.
Set BEM element and modifiers without overwriting block name.
Set BEM modifiers without overwriting block name.
Parameter | Type | Description |
---|---|---|
block | string | Overwrite block and name component value |
element | string, array | Define class element value |
modifiers | string, array, object | Define modifiers for current block/element |
All pull requests and suggestions are welcome.