@verstaerker/vue bem

A Vue.js directive and mixin to create BEM class names.

Version: 1.2.0 Updated: 01/10/2019

By: verstaerker License: MIT

Downloads Last 30 Days: 109

Install

npm i @verstaerker/vue-bem
yarn add @verstaerker/vue-bem

Repository: https://github.com/verstaerker/vue-bem

CDNs

bundle.run: https://bundle.run/@verstaerker/vue-bem

jsDelivr: https://cdn.jsdelivr.net/npm/@verstaerker/vue-bem

unpkg: https://unpkg.com/@verstaerker/vue-bem

@verstaerker/vue-bem

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.

Table of Contents

Comparison

@verstaerker/vue-bem vue-bem-cn vue-bem (Vue 1)
Info
  • Automatic class creation for block, element, modifier
  • Component name or custom property used as block name
  • Dynamic modifiers
  • Allows Boolean, Number and String values as modifiers
  • Prevents re-calculation of classes if modifiers did not change
  • Cache for String replacements
  • Only updates modifier classes on re-calculation
  • Automatic class creation for block, element, modifier and mixin
  • Component name or custom property used as block name
  • Dynamic element name
  • Dynamic modifiers
  • Dynamic mixins
  • Allows Boolean, Number and String values for modifiers
  • Automatic class creation for block, element, modifier
Limitations
  • Static element name
  • Mixins must be defined with class attribute
  • Modifiers must be defined as computed property to allow "caching"
  • No caching
  • Recalculates on each component update
  • Updates all BEM classes when re-calculating
  • Deprecated
  • Static element and modifiers

How to use

Directive

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.

Mixin

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>]);
}

Modifiers and static 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.

Attributes

Element (String)

The element name which will be concatenated with the block name using the element delimiter as glue.

Modifier (Object)

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 and Number 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

Install

To install the npm package run

npm i @verstaerker/vue-bem --save

Directive

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(/* ... */);

Mixin

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');

    // ...
  }
}

Settings

// Defaults
{
  namespace: '',
  blockSource: 'name'
  method: '$bem'
  hyphenate: {
    blockAndElement: false,
    modifier: true,
  },
  delimiters: {
    element: '__',
    modifier: '--',
    value: '-',
  }
}

namespace (String)

default: ''

Can be used to add a static namespace to the beginning of every class. Must include the delimiter.

blockSource (String)

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.

method (String)

default: $bem

Defines the name of the bem method when used as mixin.

hyphenate (Boolean|Object)

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.

delimiters (Object)

default: { element: '__', modifier: '--', value: '-', }

Allows to define custom delimiters between block, element and modifier.

delimiters.element (String)

delimiters.modifier (String)

delimiters.value (String)

Examples

The following examples show how to create block, element and modifier classes. You can combine the directive with static or dynamic class bindings.

Directive

Only block

<div v-bem></div>

<!-- will become -->
<div class="block"></div>

Only element

<div v-bem:element></div>

<!-- will become -->
<div class="block__element"></div>

With static modifier(s)

Note: There is no limit to the number of modifiers.

<div v-bem.columnRight></div> 

<!-- will become -->
<div class="block block--column-right"></div>

With dynamic modifier(s)

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>

With static and dynamic modifier(s)

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>

All together

<!-- `modifiers` is a computed value returning `{ visible: true }` -->
<div v-bem:element="modifiers"></div>

<!-- will become -->
<div class="block__element block__element--visible"></div>

Mixin

Only block

render(h) {
  const className = this.$bem(); // 'block'
}

With modifier(s)

render(h) {
  const className = this.$bem('element'); // 'block__element'
}

Only 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'
}

All together

computed: {
  modifiers() {
    return {
      visible: this.$props.visible
    }
  }
},
render(h) {
  const className = this.$bem('element', this.modifiers); // 'block__element block__element--visible'
}

Dependencies

This Vue.js plugin/mixin has no 3rd party dependencies.

License

MIT

Categories: Vue js