✅ vue-bem-cn - Simple BEM class name generator for Vue.JS

Related tags

CSS vuejs vue bem classname
Overview

vue-bem-cn

Travis npm vue-version

Simple BEM-style class name generator for Vue.JS 2.*

Table of Contents

Quick example

Live demo: codepen

Block ui-button. Vue Single File Component:

<script>
  export default {
    name: 'ui-button', // set block name
    props: ['size', 'look', 'type', 'icon'],
  }
</script>

<template>
  <button :class="b({ size, look })" :type="type">
    <span :class="b('text', { look })">
      <i v-if="icon" :class="b('icon', { icon })"> 👍 </i>
      <slot></slot>
    </span>
  </button>
</template>

Using ui-button block in App.vue:

<script>
  import Button from 'components/UI/Button.vue';

  export default {
    components: {
      'ui-button': Button
    },
  }
</script>

<template>
  <div class="example">
    <ui-button type="button" class="mix-any-class" size="large" look="primary" icon="emoji"> I am BEM button! </ui-button>
  </div>
</template>

Will be compile to:

<div class="example">
 <button class="mix-any-class ui-button ui-button--size-large ui-button--look-primary" type="button">
    <span class="ui-button__text ui-button__text--look-primary">
    <i class="ui-button__icon ui-button__icon--icon-emoji">👍 </i>
      I am BEM button!
    </span>
  </button>
</div>

Installation

npm i --save vue-bem-cn / yarn add vue-bem-cn

And install with Vue.use() in your main.js:

import vueBemCn from 'vue-bem-cn';

Vue.use(vueBemCn, {/* Your config, not required. See below */});

new Vue({...});
  • from CDN:
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<script src="https://unpkg.com/vue-bem-cn/dist/vue-bem-cn.umd.min.js"></script>
<script>
  Vue.use(vueBemCn, {/* Your config, not required. See below */});

  new Vue({...});
</script>

Usage

For class name generation, enough to call b() method with v-bind:class or use :class in your template. The Block name will be receive from name field of component or block field:

<script>
  export default {
    name: 'ui-button',
  }
</script>

<template>
  <div :class="b()"> DIV tag will receive 'ui-button' class name </div>
</template>

More examples in API section

After component initialization (created lifecycle hook), every component, that has string in name or block fields recive b() method. Also, you can call this.b() method in your component, if you need it.

Q: What if I don't want to use name field for Block name? And what is block field ?

If you want, you can use block field instead of name, but keep in mind, block prefer then name:

<script>
export default {
  name: 'ui-button',
  block: 'bem-button', // prefer then `name: 'ui-button'`
}
</script>

<template>
  <div :class="b()"> DIV tag will receive 'bem-button' class name </div>
</template>

Q: I will want use another delimiters for BEM entities. And still I need namespances.

No problem. You can set your settings object with Vue.use() as second argument:

  import Vue from 'vue';
  import vueBemCn from 'vue-bem-cn';

  // default delimiters settings
  const bemConfig = {
    delimiters: {
      ns: '', // namespace
      el: '__', // element delimeter
      mod: '--', // modifier delimeter
      modVal: '-', // value delimeter for modifier
    }
  }

  Vue.use(vueBemCn, bemConfig);

  new Vue({...});

Q: I will want use another name for b method.

Just change methodName option in config:

  import Vue from 'vue';
  import vueBemCn from 'vue-bem-cn';

  const bemConfig = {
    methodName: 'bem',
  }

  Vue.use(vueBemCn, bemConfig);

  new Vue({...});

Q: What about converting camelCase to kebab-case?

Check hyphenate option:

  import Vue from 'vue';
  import vueBemCn from 'vue-bem-cn';

  const bemConfig = {
    hyphenate: true,
  }

  Vue.use(vueBemCn, bemConfig);

  new Vue({...});

API

Block

Generate block name.

<script>
  export default {
    name: 'ui-button',
  }
</script>

<template>
  <div :class="b()"> DIV tag will receive 'ui-button' class name </div>
</template>

Modifier of Block

Generate modifier of block name.

<script>
  export default {
    name: 'ui-button',
  }
</script>

<template>
  <div :class="b({ size: 'large' })"> DIV tag will receive 'ui-button ui-button--size-large' class name </div>
</template>

Element of Block

Generate element of block name.

<script>
  export default {
    name: 'ui-button',
  }
</script>

<template>
  <div :class="b('text')"> DIV tag will receive 'ui-button__text' </div>
</template>

Modifier of Element

Generate modifier of element name.

<script>
  export default {
    name: 'ui-button',
  }
</script>

<template>
  <div :class="b('text', { look: 'primary' })"> DIV tag will receive 'ui-button__text ui-button__text--look-primary' class name </div>
</template>

Mixins

Mix class names to block/element.

  • with vue-bem-cn in your component:
<script>
  export default {
    name: 'ui-button',
  }
</script>

<template>
  <div>
    <div :class="b(false, 'block-mixin')"> DIV tag will receive 'ui-button block-mixin' class name </div>
    <div :class="b('text', 'element-mixin')"> DIV tag will receive 'ui-button__text element-mixin' class name </div>
  </div>
</template>
  • with Vue class attribute in parent component:
<script>
  import Button from 'components/UI/Button.vue';

  export  default {
    name: 'form',
    components: {
      'ui-button': Button
    },
  }
</script>

<template>
  <form :class="b()">
    <ui-button :class="b('button')"> ui-button root tag will receive 'form__button ui-button' class name </ui-button>
  </form>
</template>

Default settings

{
  hyphenate: false,
  methodName: 'b',
  delimiters: {
    ns: '',
    el: '__',
    mod: '--',
    modVal: '-'
  }
}
  • hyphenate: boolean - hyphenation the resulting class name
// { hyphenate: true }

b({ hasFocus: true }) // block--has-focus
  • methodName: string - name of the method for generating the class name
// { methodName: 'bem' }

b('elem') // [Vue warn]: Property or method "b" is not defined...
bem('elem') // block__elem
  • delimiters: Object<string> - delimiters for BEM entities
// { delimiters: { ns: 'b-', modVal: '_'} }

b({ mod: 'val' }) // b-block b-block--mod_val
Comments
  • Modifier conversion

    Modifier conversion

    I was actually expecting, that writing a modifier name in camelCase would be converted to kebab-case:

    <div :class="b('element', {fullLength: true})">

    But it's not. I get .block__element-fullLength. Would it be able to add a setting so this behaviour could be change, to use the key as kebab-case (e.g. .block__element--full-width)?

    opened by patric-eberle 4
  • Falling UglifyJS with newest versions of vue-cli/webpack

    Falling UglifyJS with newest versions of vue-cli/webpack

    In version 0.1.0, package.json has module field with a link to the source file that is not compiled with babel. In new versions of vue-cli, this can break building with Uglify, because Uglify does not understand ES6. In next patch version of vue-bem-cn,module field will remove to favormain field, for using UMD build by default. Next major version of vue-bem-cn, will be using new build system with correct compiling (thx to Rollup :)

    enhancement 
    opened by c01nd01r 0
  • Feature/improvements

    Feature/improvements

    This PR tries to reduce the amount of fallback merges and conditions. This PR should not break or extend any functionality.

    • src/bem-cn/bem-names.js
      • The configuration fallback was removed since it will always be available from the method caller (as long as kept inside plugin scope).
      • The conditions were rearenged to reduce number of evaluations.
    • src/bem-cn/index.js
      • The configuration fallback was removed since it will always be available from the method caller (as long as kept inside plugin scope).
      • The conditions were rearenged to reduce number of evaluations.
    • src/globals.js
      • The fallback config has been moved to it's own file. Initially this was because it was needed by multiple methods. In the meantime it's only purpose is to also be usable for the tests.
    • src/utils.js
    • Some of the conditions were removed since they are covered by others. (e.g. val can not be null anymore if val && typeof val === 'Object' where true already.
    • src/vue-plugin.js
      • Uses now external fallback config.
      • Reuse of isString method.
    • The tests had to be adjusted so they always deliver the now needed configuration.

    I also tested this with our current project.

    enhancement 
    opened by patric-eberle 3
  • Performance

    Performance

    We're binding our classes to a b() method. Doesn't that mean that the b() method gets processed everytime the template re-renders?

    What is the performance hit?

    opened by pdcmoreira 7
  • Proposal: Configuration Option to Convert Component Name to Kebab Case

    Proposal: Configuration Option to Convert Component Name to Kebab Case

    As the official Vue Style Guide recommends using pascal case naming for components, I would like to propose adding a configuration option to convert the component's name into kebab case for the CSS block class name. I know that right now it is possible to add a block attribute onto the component with another name to override what the component is named but this means re-writing every component name in kebab case manually to adhere to the style guide and BEM naming conventions.

    I would be willing to work on a PR for this if you want. If so, please let me know and if you have any guidance or preferences on how that should be accomplished. Thanks.

    opened by mlturner88 0
  • Proposal: Hook to allow mixin modifiers

    Proposal: Hook to allow mixin modifiers

    We just had a case, where we move the state handling of form fields to a mixin. Based on the current state of an element we update the modifier classes on the root element of a component. Currently I don't see an option, how we could automatically inject modifier classes from the mixin into b(). We currently defined a computed property which merges component and mixin states into one object.

    I couldn't find a solution for this problem in your documentation. Therefore I wanted to propose a hook for b() which would be triggered on the component when ever b() calculates classes which would allow to extend the properties of the initial call. The hook then could be added by a mixin.

    e.g. modifying the modifiers on the block element (b())

    /**
     * @param   {object}    config
     * @param   {string}    config.block
     * @param   {string}    config.element
     * @param   {object}    config.modifiers
     * @param   {string}    config.mixins
     */
    myHookMethod(config) {
      if (!config.element) {
        config.modifiers.state = 'active';
      }
    
      return config;
    }
    
    opened by patric-eberle 0
Releases(1.1.1)
Owner
Stanislav
Front-end developer
Stanislav
Simple adding class names mods to all components in your vue app

vue-mods-names Simple adding class names mods to all components in your vue app Docs with examples and playgrounds: English Русский Українська françai

RG.RU 22 Nov 18, 2022
Seamless mapping of class names to CSS Modules inside of Vue components.

English | ???? 中文 Vue CSS Modules Seamless mapping of class names to CSS modules inside of Vue components. yarn add vue-css-modules CDN: jsDelivr | UN

Jay Fong 38 Oct 16, 2021
Vue.js CSS class variant resolver. Presented as handy composable.

Vue Use Variant Simple composable for Vue.js* to handle long and ugly CSS class chaining. Read the story behind this package here. *you can use it wit

Lukas Borawski 35 Oct 28, 2022
CV generator built with Nuxt.js and TailwindCSS. Responsive design and deployed in Netlify.

CV generator built with Nuxt.js and TailwindCSS. Responsive design and deployed in Netlify.

Claudia Benito 154 Jan 1, 2023
Tailwind Gradient Generator

Tailwind Gradient Generator

Eliut Gon 31 Dec 9, 2022
Contact Us widget generator. plugin for Vuepress 可以自动生成联系我们按钮的插件

Vuepress Plugin: Contact Us Form This plugin will automatically put a floating button at the left-bottom corner, once it's clicked, a contact us form

Justin Wang 6 Sep 23, 2022
Vue-sx is a simple library that allows you to write clean CSS-in-JS for Vue

Vue-sx is a simple library that allows you to write clean CSS-in-JS for Vue

Alexandru Ghiura 4 Oct 21, 2022
🌗 Really simple dark mode switcher in Vue

?? Getting started yarn add vue-dark-mode-switcher npm install vue-dark-mode-switcher ??‍?? Usage If you love emoticons you can use base version with

Lotrèk 9 Aug 8, 2022
Simple, performant styler for vue

vue-styler Installation Install via NPM... $ npm install vue-styler ...and require the plugin like so: import VueStylerPlugin from 'vue-styler' Vue.us

Tengfei 4 Jul 30, 2020
Basic and Simple Live IPL Cricket Score site Build using Vue.js and Tailwind CSS

Live IPL Cricket Score Basic and Simple Live IPL Cricket Score site Build using Vue.js and Tailwind CSS This is an Demo and Sample site - Just clone o

Santhosh Veer 1 Aug 11, 2022
💥 A simple and beautiful vuepress Blog & Doc theme.

?? A simple and beautiful vuepress Blog & Doc theme.

vuepress-reco 264 Jan 3, 2023
Vue Start - Turn any JSON into Vue 3 tables

Vue Start Turn any JSON into Vue 3 tables! Introduction Create well coded Vue 3 tables with Bootstrap, Tailwind CSS or vanilla CSS. Try it online at v

null 49 Dec 1, 2022
Amazing collection of Vue spinners components with pure css.

Vue Spinners CSS Loaders (React, Angular) Amazing collection of Vue spinners components with pure css. The Vue spinners are based on loading.io and fr

Josh Kuttler 51 Nov 24, 2022
A website simulating Ubuntu's GUI, base on Vue + TailCSS, keep adding new features, you can access

A website simulating Ubuntu's GUI, base on Vue + TailCSS, keep adding new features, you can access

null 49 Dec 28, 2022
Tailwind CSS Button Components built with Vite, Vue, and Tailwind JIT

This is a blog post/tutorial for creating button components using Tailwind CSS. As a bonus we'll leverage some modern tools like Vite and Tailwind's new JIT feature which makes local developement with Tailwind CSS blazing fast.

Andy Leverenz 8 Dec 27, 2022
Vue 3 + Typescript + Vite + TailwindCSS Minesweeper

Vue 3 + Typescript + Vite + TailwindCSS Minesweeper Windows 3.11 Minesweeper clone with only Vue 3 + TailwindCSS To run locally Clone this project git

Alfonso Bribiesca 7 Aug 26, 2022
A Slidev Theme for my talks about Vue.js

slidev-theme-vuetiful A Vue-inspired theme for Slidev. Live demo: https://slidev-theme-vuetiful.netlify.app/ Features Pretty Vue Theme Subtle Animatio

Thorsten Lünborg 57 Dec 23, 2022
Portfolio Website for Vishesh Bansal built in Vue.js

Portfolio Website for Vishesh Bansal built in Vue.js

Vishesh Bansal 47 Dec 9, 2022
Shopify Foundation Theme is modern Shopify theme built with Shopify Theme Lab, Vue and Tailwind CSS.

Modern Shopify theme using Shopify Theme Lab, Liquid, Vue and Tailwind CSS ??

UI Crooks 218 Jan 4, 2023