Adds a directive and (optional) mixin to your Vue.js project to create BEM class names.
This Plugin was inspired by vue-bem-cn and vue-bem.
@verstaerker/vue-bem | vue-bem-cn | vue-bem (Vue 1) | |
---|---|---|---|
Info |
|
|
|
Limitations |
|
|
|
The vue-bem directive is used as any other Vue.js directive.
v-bem<:element><.static-modifiers>="<modifiers>"
All parts are optional. If you only use v-bem
you will still get the block class though.
The mixin adds a $bem
(or as configured) method to the extended component which you can use to create BEM classes from within JavaScript.
render(h) {
const className = this.$bem(<element> [, <modifiers>]);
}
You can define two types of modifiers: dynamic and static. The dynamic ones can be given as value object to the directive (e.g. v-bem="{ status: 'error' }
[note, that it is better practice to define a computed for modifiers to allow conditional updates]). Static ones can be defined as directive modifiers (e.g. v-bem.column-right
). The advantage of static modifiers is the fact, that they will only be defined once when the component is rendered. Dynamic modifiers will overwrite static modifiers with the same (initial) name.
The element name which will be concatenated with the block name using the element
delimiter as glue.
The to be applied modifiers which will be concatenated with the block or element name using the modifier
delimiter as glue.
A value can be given to each modifier (which will be concatenated using the value
delimiter as glue):
- Type
String
andNumber
will be added as a value to the modifier class - Type
Boolean
will add/remove the modifier and not add a value to the modifier
To install the npm package run
npm i @verstaerker/vue-bem --save
The directive is delivered as a Vue plugin. You can install it as any other plugin:
import Vue from 'vue';
import vueBem from '@verstaerker/vue-bem';
Vue.use(vueBem);
new Vue(/* ... */);
To use the mixin you MUST install the plugin first. Then you can use the mixin as any other Vue mixin (locally or globally). It is recommended to use the mixin locally when needed.
// component.vue
import { bemMixin } from '@verstaerker/vue-bem'
export default {
mixins: [bemMixin],
render(h) {
const className = this.$bem('element');
// ...
}
}
// Defaults
{
namespace: '',
blockSource: 'name'
method: '$bem'
hyphenate: {
blockAndElement: false,
modifier: true,
},
delimiters: {
element: '__',
modifier: '--',
value: '-',
}
}
default: ''
Can be used to add a static namespace to the beginning of every class. Must include the delimiter.
default: name
Defines the component property which will be used to create the BEM block name. name
will also be used as fallback in case the given blockSource is not available.
default: $bem
Defines the name of the bem method when used as mixin.
default: { blockAndElement: false, modifier: true }
Allows to enable auto hyphenating of block
, element
and modifiers
. Mixins are never touched. By default hyphenating is only applied to modifiers
to allow the use of camelCase key names for the modifier Object. It is recommended to write block
and element
already in kebab case if you prepare so because it removes the conversion step. Hyphenation for modifiers
will apply for static and dynamic modifiers.
default: { element: '__', modifier: '--', value: '-', }
Allows to define custom delimiters between block
, element
and modifier
.
The following examples show how to create block, element and modifier classes. You can combine the directive with static or dynamic class bindings.
<div v-bem></div>
<!-- will become -->
<div class="block"></div>
<div v-bem:element></div>
<!-- will become -->
<div class="block__element"></div>
Note: There is no limit to the number of modifiers.
<div v-bem.columnRight></div>
<!-- will become -->
<div class="block block--column-right"></div>
Note: There is no limit to the number of modifiers.
<!-- `modifiers` is a computed value returning `{ color: 'red' }` -->
<div v-bem="modifiers"></div>
<!-- will become -->
<div class="block block--color-red"></div>
Note: There is no limit to the number of modifiers.
<!-- `modifiers` is a computed value returning `{ color: 'red' }` -->
<div v-bem.columnRight="modifiers"></div>
<!-- will become -->
<div class="block block--column-right block--color-red"></div>
<!-- `modifiers` is a computed value returning `{ visible: true }` -->
<div v-bem:element="modifiers"></div>
<!-- will become -->
<div class="block__element block__element--visible"></div>
render(h) {
const className = this.$bem(); // 'block'
}
render(h) {
const className = this.$bem('element'); // 'block__element'
}
Note: There is no limit to the number of modifiers.
computed: {
modifiers() {
return {
color: this.$props.color
}
}
},
render(h) {
const className = this.$bem(this.modifiers); // 'block block--color-red'
}
computed: {
modifiers() {
return {
visible: this.$props.visible
}
}
},
render(h) {
const className = this.$bem('element', this.modifiers); // 'block__element block__element--visible'
}
This Vue.js plugin/mixin has no 3rd party dependencies.
MIT