Skip to content

element plus css架构之useNamespace #3

@Stream-web

Description

@Stream-web

useNamespace 是 Element Plus 中用于定义命名空间和 BEM 规范的 CSS 类名的组合式 API。它主要用于在组件中使用命名空间和 BEM 规范的 CSS 类名,以避免 CSS 类名冲突和提高代码可读性。

useNamespace 函数接受两个参数:block 和 namespaceOverrides。其中,block 表示块名,namespaceOverrides 表示命名空间的覆盖值。如果传入了命名空间的覆盖值,则使用覆盖值作为命名空间;否则,如果当前组件存在,则从组件中获取命名空间;否则,使用默认的命名空间。

useNamespace 函数返回一个对象,包含了命名空间、一系列生成 CSS 类名的函数、生成 CSS 变量名的函数以及一个类型别名 UseNamespaceReturn,用于表示 useNamespace 函数的返回值类型。

在 Element Plus 中,useNamespace 函数被广泛用于定义组件的 CSS 类名,以确保组件的样式不会与其他组件的样式冲突。
具体代码如下:
`import { computed, getCurrentInstance, inject, ref, unref } from 'vue'

import type { InjectionKey, Ref } from 'vue'

export const defaultNamespace = 'el'
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 namespaceContextKey: InjectionKey<Ref<string | undefined>> =
Symbol('namespaceContextKey')

export const useGetDerivedNamespace = (
namespaceOverrides?: Ref<string | undefined>
) => {
const derivedNamespace =
namespaceOverrides ||
(getCurrentInstance()
? inject(namespaceContextKey, ref(defaultNamespace))
: ref(defaultNamespace))
const namespace = computed(() => {
return unref(derivedNamespace) || defaultNamespace
})
return namespace
}

export const useNamespace = (
block: string,
namespaceOverrides?: Ref<string | undefined>
) => {
const namespace = useGetDerivedNamespace(namespaceOverrides)
const b = (blockSuffix = '') =>
_bem(namespace.value, block, blockSuffix, '', '')
const e = (element?: string) =>
element ? _bem(namespace.value, block, '', element, '') : ''
const m = (modifier?: string) =>
modifier ? _bem(namespace.value, block, '', '', modifier) : ''
const be = (blockSuffix?: string, element?: string) =>
blockSuffix && element
? _bem(namespace.value, block, blockSuffix, element, '')
: ''
const em = (element?: string, modifier?: string) =>
element && modifier
? _bem(namespace.value, block, '', element, modifier)
: ''
const bm = (blockSuffix?: string, modifier?: string) =>
blockSuffix && modifier
? _bem(namespace.value, block, blockSuffix, '', modifier)
: ''
const bem = (blockSuffix?: string, element?: string, modifier?: string) =>
blockSuffix && element && modifier
? _bem(namespace.value, block, blockSuffix, element, modifier)
: ''
const is: {
(name: string, state: boolean | undefined): string
(name: string): string
} = (name: string, ...args: [boolean | undefined] | []) => {
const state = args.length >= 1 ? args[0]! : true
return name && state ? ${statePrefix}${name} : ''
}

// for css var
// --el-xxx: value;
const cssVar = (object: Record<string, string>) => {
const styles: Record<string, string> = {}
for (const key in object) {
if (object[key]) {
styles[--${namespace.value}-${key}] = object[key]
}
}
return styles
}
// with block
const cssVarBlock = (object: Record<string, string>) => {
const styles: Record<string, string> = {}
for (const key in object) {
if (object[key]) {
styles[--${namespace.value}-${block}-${key}] = object[key]
}
}
return styles
}

const cssVarName = (name: string) => --${namespace.value}-${name}
const cssVarBlockName = (name: string) =>
--${namespace.value}-${block}-${name}

return {
namespace,
b,
e,
m,
be,
em,
bm,
bem,
is,
// css
cssVar,
cssVarName,
cssVarBlock,
cssVarBlockName,
}
}

export type UseNamespaceReturn = ReturnType
`
下列函数分别用于生成符合 BEM 规范的 CSS 类名,具体含义如下:

b(blockSuffix?: string): string:生成块名的 CSS 类名,可选参数 blockSuffix 用于生成带有块后缀的 CSS 类名。

e(element?: string): string:生成元素名的 CSS 类名,可选参数 element 用于生成带有元素名的 CSS 类名。

m(modifier?: string): string:生成修饰符的 CSS 类名,可选参数 modifier 用于生成带有修饰符的 CSS 类名。

be(blockSuffix?: string, element?: string): string:生成块名和元素名的组合 CSS 类名,可选参数 blockSuffix 用于生成带有块后缀的 CSS 类名,可选参数 element 用于生成带有元素名的 CSS 类名。

em(element?: string, modifier?: string): string:生成元素名和修饰符的组合 CSS 类名,可选参数 element 用于生成带有元素名的 CSS 类名,可选参数 modifier 用于生成带有修饰符的 CSS 类名。

bm(blockSuffix?: string, modifier?: string): string:生成块名和修饰符的组合 CSS 类名,可选参数 blockSuffix 用于生成带有块后缀的 CSS 类名,可选参数 modifier 用于生成带有修饰符的 CSS 类名。

bem(blockSuffix?: string, element?: string, modifier?: string): string:生成块名、元素名和修饰符的组合 CSS 类名,可选参数 blockSuffix 用于生成带有块后缀的 CSS 类名,可选参数 element 用于生成带有元素名的 CSS 类名,可选参数 modifier 用于生成带有修饰符的 CSS 类名。

is(name: string, state?: boolean): string:用于生成状态类名,接受两个参数,name 表示状态名称,state 表示状态值,如果 state 为 true,则返回以 is- 为前缀的状态类名,否则返回空字符串。

cssVar(object: Record<string, string>): Record<string, string>:用于生成 CSS 变量名,接受一个对象参数 object,该对象的键表示变量名,值表示变量值,返回一个对象,其中键为以命名空间、变量名和前缀 -- 组成的字符串,值为变量值。

cssVarName(name: string): string:用于生成 CSS 变量名,接受一个字符串参数 name,返回以命名空间、name 参数和前缀 -- 组成的字符串,用于在 CSS 中定义变量。

cssVarBlock(object: Record<string, string>): Record<string, string>:用于生成带有块名的 CSS 变量名,接受一个对象参数 object,该对象的键表示变量名,值表示变量值,返回一个对象,其中键为以命名空间、块名、变量名和前缀 -- 组成的字符串,值为变量值。

cssVarBlockName(name: string): string:用于生成带有块名的 CSS 变量名,接受一个字符串参数 name,返回以命名空间、块名、name 参数和前缀 -- 组成的字符串,用于在 CSS 中定义带有块名的变量。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions