DEV Community

Kesion
Kesion

Posted on

How to elegantly use BEM in vue3

In team development, we need to formulate css naming conventions, and the BEM specification is one of the css naming conventions. Our project was developed with vue3, and I didn't find the BEM framework that I wanted on the Internet, so I wrote one myself, then I will introduce vue3-bem to you.

vue3 bem

Installation

npm i vue3-bem

Using

vue3-bem is also very easy to use. As shown below.

// .vue
import useBem from "vue3-bem";
const bem = useBem("block");
Enter fullscreen mode Exit fullscreen mode
<div :class="bem('elem', 'selected')"></div>
Enter fullscreen mode Exit fullscreen mode
.block {
  &__elem {
    &--selected {
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Api

Use useBem to set the block.

Use bem to configure elements and modfiers to return classes.

type BemFunction = function (
    e?: string | null,
    m?: string | string[] | { [key in string]: boolean }
) => string[];

function useBem(block: string) => BemFunction;

bem: BemFunction
Enter fullscreen mode Exit fullscreen mode

Tools

If you think it's too much trouble to write import for each component, you can use the plugin vite-plugin-vue3-bem so you don't need to write import vue3-bem.

Use vite-plugin-vue3-bem can help you remove import.

// .vue
<template>
  <div :class="bem('elem', 'selected')"></div>
</template>

<script lang="ts" bem-block="tip">
// do some thing
</script>

<style lang="less"> 
.tip {
  &__elem {
    &--selected {
    }
  }
}
</style>
Enter fullscreen mode Exit fullscreen mode
// vite.config.js
import ViteVue3Bem from "vite-plugin-vue3-bem";

plugins:[
    ViteVue3Bem()
]
Enter fullscreen mode Exit fullscreen mode

Type Declaration
Type declaration is required in typescript to prevent error reporting.

// env.d.ts
import "vue3-bem";
Enter fullscreen mode Exit fullscreen mode

Example

Custom block name

<div class="tip">
    <div :class="bem("wrap")"></div>
</div>
Enter fullscreen mode Exit fullscreen mode
<script setup>
import useBem from "./useBem";
const bem = useBem('tip');
</script>
Enter fullscreen mode Exit fullscreen mode
.tip {
    &__wrap {
    }
}
Enter fullscreen mode Exit fullscreen mode

Inline modfiers

<div :class="bem('container')">
    <div :class="bem("header")"></div>
    <div :class="bem('item',  ["selected", "highlighted"])"></div>
</div>
Enter fullscreen mode Exit fullscreen mode
<script setup>
import useBem from "./useBem";
const bem = useBem('tip');
</script>
Enter fullscreen mode Exit fullscreen mode
.tip {
    &__header {
    }
    &__item {
        &--selected {
        }
        &--highlighted {
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Conditional modfiers

<div :class="bem('container')">
    <div :class="bem("header")"></div>
    <div :class="bem('item',  {"selected": true, "highlighted": highlighted})"></div>
</div>
Enter fullscreen mode Exit fullscreen mode
<script>
    import useBem from "./useBem";
    const bem = useBem('tip');
    const highlighted = ref(false);
</script>
Enter fullscreen mode Exit fullscreen mode
.tip {
    &__header {
    }
    &__item {
        &--selected {
        }
        &--highlighted {
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Give a star if you think it will help you.

github: vue3-bem

Discussion (0)