Simple implementation of BEM in Vue 3.x
Based on Vue 2.x library vue-bem-cn
npm i @vuebits/bem
/ yarn add @vuebits/bem
And install in your entry file (e.g. main.js
):
import { createBem } from '@vuebits/bem';
createApp(App).use(createBem({ /* your config here */ })).mount('#app');
createBem (options: BemOptions)
:
interface BemOptions {
hyphenate?: boolean;
}
$bem ({ b, e, m }: BemItem): string[]
:
interface BemItem {
b?: string;
e?: string;
m?: string | string[] | {[key in string]: boolean};
}
<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>
If you use PascalCase naming convence you should init library with hyphenate
option:
import { createBem } from '@vuebits/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>
<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>
<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>
<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>
<template>
<div :class="$bem({})"> <!-- returns ['hello-world'] -->
<p :class="$bem({e: 'description', m: {underlined: true, highlighted: isHighlighted}})"> <!-- returns ['hello-world__description', 'hello-world__description--underlined'] -->
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
}
}
}
</style>