【Nova UI】四、JavaScript 与 BEM 规范的梦幻联动:前端开发新动能

序言

我们已经领略了 BEM 规范在 CSS 样式管理方面的强大功能🌌,它为我们的样式代码带来了秩序与高效。但在前端开发中,JavaScript 作为交互逻辑的核心语言,与 CSS 紧密协作🤝。那么,如何让 BEM 规范在 JavaScript 中发挥作用,实现更高效的代码编写和维护呢🧐?这正是我们即将深入探讨的内容。在接下来的篇章里,我们将逐步揭开 JavaScript 实现 BEM 规范的神秘面纱,为你的前端开发技能库增添重要的一环💪。

举例

深入探究 BEM 规范在 CSS 领域的卓越效能后,我们已然明晰块(Block)、元素(Element)、修饰符(Modifier)是如何彼此协同,构建起一套条理清晰、结构化的样式管理体系的。然而,在前端开发的广阔版图中,当我们将视角聚焦于组件开发时,一个至关重要的要素 —— 状态(State),如同夜空中一颗悄然升起的新星🌟,逐渐进入我们的视野。它与 BEM 规范深度融合、相互交织,共同为组件赋予了更为丰富的交互性与动态表现力。

以我们日常开发中频繁使用的 Button 组件为例,它看似简约,实则暗藏诸多精巧设计。请瞧下面这段 HTML 代码:

<button class="button button--primary is-disabled">
    <i class="button__icon"></i>
    <span class="button__text">提交</span>
</button>

在这段代码里,button作为 Button 组件的块,奠定了组件的基本结构与核心功能🏗️,任何对按钮的通用样式设定与基础交互逻辑,都围绕这个块展开。button__icon无疑是 Button 组件的图标元素。而button--primary则是 Button 组件的修饰符,用于改变按钮的外观风格,彰显出特定的样式特征👗。至于is-disabled,它代表了 Button 组件的状态,表明该按钮当前处于禁用状态🚫。

有了上述对 Button 组件基于 BEM 规范与状态的清晰认知,我们在 JavaScript 中实现相关功能的思路也逐渐清晰起来。

实现

市面上的组件库都有自己独特的命名空间,就像 element 组件库,它的组件都是以el-开头的。为了让我们的组件在代码之林中也能拥有清晰的标识,自然也要打造自己专属的命名空间🚩。

我们在packages/hooks/use-namespace目录下新增index.ts文件,开启构建我们的 BEM 命名空间之旅。

export const defaultNamespace = 'n'
const statePrefix = 'is-'

const _bem = (
  namespace: string,
  block: string,
  blockSuffix: string,
  element: string,
  modifier: string
) => {
  let cls = `${namespace}-${block}`
  if (blockSuffix) {
    cls += `-${blockSuffix}`
  }
  if (element) {
    cls += `__${element}`
  }
  if (modifier) {
    cls += `--${modifier}`
  }
  return cls
}

export const useNamespace = (block: string) => {
  const namespace = defaultNamespace
  const b = (blockSuffix = '') => _bem(namespace, block, blockSuffix, '', '')
  const e = (element?: string) => (element ? _bem(namespace, block, '', element, '') : '')
  const m = (modifier?: string) => (modifier ? _bem(namespace, block, '', '', modifier) : '')

  const be = (blockSuffix?: string, element?: string) =>
    blockSuffix && element ? _bem(namespace, block, blockSuffix, element, '') : ''
  const bm = (blockSuffix?: string, modifier?: string) =>
    blockSuffix && modifier ? _bem(namespace, block, blockSuffix, '', modifier) : ''
  const em = (element?: string, modifier?: string) =>
    element && modifier ? _bem(namespace, block, '', element, modifier) : ''
  const bem = (blockSuffix?: string, element?: string, modifier?: string) =>
    blockSuffix && element && modifier ? _bem(namespace, block, blockSuffix, element, modifier) : ''

  const is = (name: string, state: boolean | undefined = true) =>
    state ? `${statePrefix}${name}` : ''

  return {
    namespace,
    b,
    e,
    m,
    be,
    bm,
    em,
    bem,
    is,
  }
}

在这段代码中,我们定义了一个默认的命名空间n,并通过一系列函数来生成符合 BEM 规范的类名。这些函数就像是一个个精巧的工匠🧑‍🔧,根据我们传入的块、元素、修饰符和状态等信息,打造出独一无二的类名标识,让我们在 JavaScript 中能够轻松地与遵循 BEM 规范的组件进行交互,为前端开发带来更多的便利与可能。

🦀🦀感谢看官看到这里,如果觉得文章不错的话🙌,点个关注不迷路⭐。
诚邀您加入我的微信技术交流群🎉,群里都是志同道合的开发者👨‍💻,大家能一起交流分享摸鱼🐟。期待与您在群里相见🚀,咱们携手在开发路上共同进步✨ !
👉点我

感谢各位大侠一路相伴,实在感激! 不瞒您说,在下还有几个开源项目 📦,它们就像精心培育的幼苗 🌱,急需您的浇灌。要是您瞧着还不错,麻烦动动手指,给它们点亮几颗 Star ⭐,您的支持就是它们成长的最大动力,在此谢过各位大侠啦!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值