@usepack/vue-bem
TypeScript icon, indicating that this package has built-in type declarations

1.4.1 • Public • Published

Vue 3 BEM

*** Maintainers & Contributors welcome ***

Vue.js BEM

Simple implementation of BEM in Vue 3.x

Based on Vue 2.x library vue-bem-cn


Table of Contents

Installation

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

And install in your entry file (e.g. main.js):

import { createBem } from '@usepack/vue-bem';

createApp(App).use(createBem({ /* your config here */ })).mount('#app');

API

Available functions:

  • createBem (options: BemOptions):
interface BemOptions {
  hyphenate?: boolean;
  modifierSeparator?: string;
  transformComponentName?: (name: string) => string;
}

Vue instance properties and methods:

  • $bem ({ b, e, m }: BemItem): string[]:
interface BemItem {
  b?: string;
  e?: string;
  m?: string | string[] | Record<string, string | number | boolean>;
}

Examples

Using component name by default:

<template>
  <div :class="$bem()"> <!-- $bem() will return 'hello-world' -->
    Hello world!
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue';

export default defineComponent({
  name: 'hello-world'
});
</script>

<style lang="scss">
.hello-world {
  // some styles here
}
</style>

Using hyphenated component name:

If you use PascalCase naming convence you should init library with hyphenate option:

import { createBem } from '@usepack/vue-bem';

createApp(App).use(createBem({
  hyphenate: true
})).mount('#app');

and then:

<template>
  <div :class="$bem()"> <!-- returns ['hello-world'] -->
    Hello world!
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue';

export default defineComponent({
  name: 'HelloWorld'
});
</script>

<style lang="scss">
.hello-world {
  // some styles here
}
</style>

Transforming component name before use in css class names:

If your components have name with prefix (i.e VHelloWorld) you can init library with transformComponentName option to remove prefix:

import { createBem } from '@usepack/vue-bem';

createApp(App).use(createBem({
  transformComponentName (name: string): string {
    return name.replace(/^V/, '');
  }
})).mount('#app');

and then:

<template>
  <div :class="$bem()"> <!-- returns ['hello-world'] -->
    Hello world!
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue';

export default defineComponent({
  name: 'VHelloWorld'
});
</script>

<style lang="scss">
.hello-world {
  // some styles here
}
</style>

Custom block name:

<template>
  <div :class="$bem({b: 'custom-block'})"> <!-- returns ['custom-block'] -->
    Hello world!
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue';

export default defineComponent({
  name: 'HelloWorld'
});
</script>

<style lang="scss">
.custom-block {
  // some styles here
}
</style>

Element name:

<template>
  <div :class="$bem()"> <!-- (or $bem({b: 'hello-world'})) - return ['hello-world'] -->
    <h1 :class="$bem({e: 'title'})"> <!-- (or $bem({b: 'hello-world', e: 'title'})) - returns ['hello-world__title'] -->
      Hello world!
    </h1>
    <p :class="$bem({e: 'description'})"> <!-- (or $bem({b: 'hello-world', e: 'description'})) - returns ['hello-world__description'] -->
      This is a description
    </p>
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue';

export default defineComponent({
  name: 'HelloWorld'
});
</script>

<style lang="scss">
.hello-world {
  // some styles here
  &__title {
    // some styles here
  }
  &__description {
    // some styles here
  }
}
</style>

Inline modfiers:

<template>
  <div :class="$bem()"> <!-- returns ['hello-world'] -->
    <p :class="$bem({e: 'text', m: ['underlined']})"> <!-- returns ['hello-world__text', 'hello-world__text--underlined'] -->
      This is a description
    </p>
    <p :class="$bem({e: 'text', m: ['underlined', 'highlighted']})"> <!-- returns ['hello-world__text', 'hello-world__text--underlined', 'hello-world__text--highlighted'] -->
      This is a description
    </p>
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue';

export default defineComponent({
  name: 'HelloWorld'
});
</script>

<style lang="scss">
.hello-world {
  // some styles here
  &__text {
    // some styles here
    &--underlined {
      // some styles here
    }
    &--highlighted {
      // some styles here
    }
  }
}
</style>

Conditional modifiers:

<template>
  <div :class="$bem()"> <!-- returns ['hello-world'] -->
    <p :class="$bem({e: 'description', m: {underlined: true, highlighted: isHighlighted, 'font-weight': 'bold'}})"> <!-- returns ['hello-world__description', 'hello-world__description--underlined', 'hello-world__description--font-weight--bold'] -->
      This is a description
    </p>
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue';

export default defineComponent({
  name: 'HelloWorld',
  data () {
    return {
      isHighlighted: false
    };
  }
});
</script>

<style lang="scss">
.hello-world {
  // some styles here
  &__description {
    // some styles here
    &--underlined {
      // some styles here
    }
    &--highlighted {
      // some styles here
    }
    &--font-weight {
       &--bold {
         // some styles here
       }
    }
  }
}
</style>

Using different modifier separator:

If you use _ instead of -- or another separator, you should init library with modifierSeparator option:

import { createBem } from '@usepack/vue-bem';

createApp(App).use(createBem({
  modifierSeparator: '_'
})).mount('#app');

and then:

<template>
  <div :class="$bem()"> <!-- returns ['hello-world'] -->
    <p :class="$bem({e: 'description', m: {'font-weight': 'bold'}})"> <!-- returns ['hello-world__description', 'hello-world__description_font-weight_bold'] -->
      This is a description
    </p>
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue';

export default defineComponent({
  name: 'HelloWorld',
});
</script>

<style lang="scss">
.hello-world {
  // some styles here
  &__description {
    // some styles here
    &_underlined {
      // some styles here
    }
    &_font-weight {
      &_bold {
        // some styles here
      }
    }
  }
}
</style>

Package Sidebar

Install

npm i @usepack/vue-bem

Weekly Downloads

0

Version

1.4.1

License

MIT

Unpacked Size

57.3 kB

Total Files

16

Last publish

Collaborators

  • intelrug