sx —— 样式速写
本頁內容尚未翻譯。
sx 是 lh-ui 的内联样式速写:用 mt: 4 代替 style="margin-top: 32px",用 p: 2 代替一次性写四边 padding。它不是 Tailwind(不生成类名、不引 CSS),而是运行时把属性包直接求值为 Record<string, string>,交给 UI 层绑到 :style。
- 组件库内部:
sx让组件在「布局微调」这一层不必新增 prop——<LhButton sx={{ mt: 2 }} />就能顶开上方间距。 - 需要随数据动态变化的间距:数值到 px 的换算(
×8)让「离我近一点」这类语义有了稳定刻度。 - 不该用它:成体系的视觉设计。sx 是「调用点的临时微调」,主题色、控件高度这类设计令牌仍然走 CSS 变量(见 主题系统);sx 里写
color: 'var(--lh-primary-color)'能工作,但更推荐让组件直接消费令牌。
// 精确导入(推荐,tree-shaking 友好)import { sxToStyle, mergeSx } from '@lh-ui/share/core/shared/sx'import type { LhSxProps } from '@lh-ui/share/core/shared/sx'
// 或从聚合入口import { sxToStyle } from '@lh-ui/share/core/shared'| 函数 | 签名 | 返回 | 作用 |
|---|---|---|---|
sxToStyle |
(sx: LhSxProps) => Record<string, string> |
内联样式对象 | 把 sx 属性包求值为 CSS 样式 |
mergeSx |
(...list: (LhSxProps | undefined | null)[]) => LhSxProps |
合并后的 sx | 后者覆盖前者,供 UI 层组合「默认 sx + 调用方 sx」 |
sxToStyle 的优先级规则
Section titled “sxToStyle 的优先级规则”「单边 > 轴组 > 简写」,且与键的书写顺序无关。实现上按 简写 → 轴组 → 单边 的固定顺序写入样式对象,后写覆盖先写,所以无论你怎么排键序:
sxToStyle({ m: 2, mt: 4 }) // { marginTop: '32px', marginRight: '16px', marginBottom: '16px', marginLeft: '16px' }sxToStyle({ mt: 4, m: 2 }) // 完全相同sxToStyle({ my: 2, mt: 4 }) // marginTop 单边胜出:32px;mb 仍是 16px这条规则让组件库可以安全地写「默认包 + 用户覆盖」:用户传的 mt 一定会压过组件内部的 m。
数值与字符串
Section titled “数值与字符串”- 数值按
×8px换算:mt: 4→32px。8 是 lh-ui 的间距基准(与--lh-spacing-*令牌同刻度)。 - 字符串原样透传:
w: '50%'→50%,p: '1rem'→1rem。 - 布局类键不换算:
display/flex/flexDirection/alignItems/justifyContent的值按字符串直接写入(flexDirection: 'column'不会变成columnpx)。 - 所有键统一按
!== undefined判定:传空串''视为显式清空,会被写入。
export interface LhSxProps { // 尺寸 w?: string | number h?: string | number // 外边距:单边 / 轴组 / 简写 mt?: string | number mr?: string | number mb?: string | number ml?: string | number my?: string | number mx?: string | number m?: string | number // 内边距:同构 pt?: string | number pr?: string | number pb?: string | number pl?: string | number py?: string | number px?: string | number p?: string | number // 布局 display?: string flex?: string flexDirection?: 'row' | 'column' alignItems?: string justifyContent?: string // 兼容下游自定义键;未知键会被静默丢弃 [key: string]: any}索引签名 [key: string]: any 是刻意的:各 UI 库会在自己的 LhXxxProps 里把 sx?: LhSxProps 与组件特有属性放在一起,索引签名让类型不互相冲突;未知键在求值时被丢弃,不会泄漏进样式。
sxToStyle({ mt: 2, px: 3, display: 'flex', alignItems: 'center' })// {// marginTop: '16px',// paddingLeft: '24px',// paddingRight: '24px',// display: 'flex',// alignItems: 'center',// }<!-- Vue3 / Vue2:直接绑 :style --><template> <lh-button :style="sxToStyle($props.sx)">按钮</lh-button></template>// React<div style={sxToStyle({ my: 4, w: '100%' })} />// uniapp:sxToStyle 输出的是普通对象,直接进 style 绑定// (数值 ×8px 在非 h5 端需要视平台换算,UI 层自行处理)mergeSx 的典型用法是组件内部组合默认值:
// 组件内部const merged = mergeSx({ py: 2, px: 4 }, props.sx) // 用户的 sx 覆盖默认const style = sxToStyle(merged) // 只求值一次,优先级规则只结算一遍mergeSx是浅合并(Object.assign),不递归;sx 的值都是标量,浅合并够用。sxToStyle假值返回{}:sxToStyle(undefined)是空对象,UI 层可以无脑调用。- 数值换算的 8px 基准与令牌体系对齐,但 sx 本身不引用 CSS 变量——它产出的是计算好的字面量,适合「这一次调用要偏一点」的场景,不适合「随主题变」的场景。
- 跨端:uniapp 非 h5 端的 rpx 需在 UI 层换算,sx 内核只出 px。
@lh-ui/share/core/sx → sxToStyle( )返回值
(填好参数后点运行)Copyright © 2024-2026 风默文学 | 宁ICP备2024006574号 |
苏公网安备32040002010537