uni-scss 全局辅助样式库解析:hello-uniapp 中的颜色、间距、圆角与按钮体系

原创2026-10-14 19:04:491,972 阅读
文章标签:示例工程前端

uni-scss 全局辅助样式库解析:hello-uniapp 中的颜色、间距、圆角与按钮体系

uni-scss(又名 uni-sass)是 uni-ui 生态提供的一套全局 SCSS 辅助样式库,通过简单的类名与 Sass 变量即可完成颜色、边距、圆角、阴影、文本排版等常见布局操作。本文以 hello-uniapp 仓库中 uni_modules/uni-scss 的实际源码为主线,从版本演进、目录结构、变量体系、类名生成机制到 demo 应用逐层拆解,读完你可以掌握这套样式库的设计思路,并能在自己的 uni-app 项目中直接引用、覆写与定制主题。

一、版本演进:从 1.0.0 到 1.0.3 的变更脉络

uni_modules/uni-scss/changelog.md 完整记录了这套样式库的发布历史,是理解其能力边界与兼容性要求的第一手资料:

版本 发布日期 变更内容 影响面
1.0.0 2021-11-18 初始版本发布(init) 建立变量体系与辅助类名体系
1.0.1 2021-11-22 修复 vue3 中 scss 语法兼容问题 Vue3 工程可正常编译 SCSS
1.0.2 2021-11-22 修复 / 符号在 vue 不同版本兼容问题引起的报错 根因是 SCSS 除法运算符在新旧 dart-sass / node-sass 中的写法差异
1.0.3 2022-01-21 优化组件示例 与 uni-ui 各组件联调演示更完整

值得注意的是 1.0.2 的修复点:/ 作为除法符号在 Sass 不同版本中的处理并不一致,新版本 Sass 已废弃裸除法并要求使用 math.div()。这一点在源码中留有佐证——styles/setting/_variables.scss 文件顶部被注释掉的 // @use "sass:math"; 以及 // 'sm': math.div($uni-radius-root, 2),说明开发者保留了迁移痕迹,圆角档位中 sm 档也因此暂未开放。

从 package.json 还可以确认工程约束:该模块的 engines.HBuilderX 要求 ^3.1.0,即需要 HBuilderX 3.1.0 及以上版本才能获得完整的编译支持;同时其 uni_modules 平台声明显示,Vue2 / Vue3 均支持,H5(含 PC 端 Chrome、IE、Edge、Firefox、Safari 与移动端浏览器)、微信/阿里/百度/字节/QQ 小程序均标记为可用(y),App 端 app-vue 可用、app-nvue 为未知(u),这正对应了源码中大量 #ifndef APP-NVUE 条件编译注释——nvue 下部分类名需要特殊处理。

二、目录结构与加载入口

uni-scss 在 hello-uniapp 中的目录结构如下:

uni_modules/uni-scss/
├── changelog.md            # 版本变更记录
├── index.scss              # 顶层入口(仅一行 @import)
├── variables.scss          # 对外暴露的变量清单(供直接覆写)
├── theme.scss              # 主题色概览(展示用精简变量集)
├── readme.md               # 使用说明
├── package.json            # 模块元信息与平台支持声明
└── styles/
    ├── index.scss          # 汇总导入 6 个 setting 文件
    ├── setting/
    │   ├── _variables.scss # 全部 Sass 变量(含默认值 !default)
    │   ├── _border.scss    # .uni-border 边框类
    │   ├── _color.scss     # 颜色类名生成 + 阴影/蒙版类
    │   ├── _space.scss     # 间距类名生成(margin/padding)
    │   ├── _radius.scss    # 圆角类名生成
    │   ├── _text.scss      # 文本排版类名(h1~h6 等)
    │   └── _styles.scss    # 按钮(.uni-btn)样式体系
    └── tools/
        └── functions.scss  # map-deep-merge 工具函数

加载链路非常清晰:index.scss(顶层)→ styles/index.scss → 6 个 setting/_*.scss;而 _variables.scss 又会 @import '../tools/functions.scss' 引入 map 合并工具函数。

在 hello-uniapp 项目中,这套样式在全局入口 App.vue 中加载:

<style lang="scss">
	@import '@/uni_modules/uni-scss/index.scss';
	/* uni.css - 通用组件、模板样式库,可以当作一套ui库应用 */
	@import './common/uni.css';
</style>

注意两点:一是 <style> 必须声明 lang="scss",否则 Sass 语法无法编译;二是 App.vue 中通过 @/uni_modules/uni-scss/index.scss 路径引用,@/ 指向项目根目录,符合 uni_modules 的引用规范。加载后,全部辅助类名(如 uni-primary、uni-mt-5、uni-radius)即可在任意页面直接使用。

三、变量体系:全量色板、间距、圆角与阴影

styles/setting/_variables.scss 是整套样式的心脏,几乎每个变量都带有 !default 标记,意味着你可以先声明同名变量再导入,实现"覆写主题"。

3.1 主色与辅助色(行为色)

变量 默认值 派生变量
$uni-primary #2979ff $uni-primary-disable(lighten 20%)、$uni-primary-light(lighten 25%)
$uni-success #18bc37 $uni-success-disable、$uni-success-light
$uni-warning #f3a73f $uni-warning-disable、$uni-warning-light
$uni-error #e43d33 $uni-error-disable、$uni-error-light
$uni-info #8f939c $uni-info-disable、$uni-info-light

派生色通过 Sass 内置 lighten() 函数按百分比提亮得到:disable 提亮 20%,light 提亮 25%。这与顶层 variables.scss 中的 mix(#fff, $uni-primary, 50%) 写法略有差异(mix 是按比例混合白色),但语义一致,均用于表达禁用态与浅色态。

3.2 中性色、边框色与常规色

// 中性色(文字层级)
$uni-main-color: #3a3a3a;      // 主要文字
$uni-base-color: #6a6a6a;      // 常规文字
$uni-secondary-color: #909399; // 次要文字
$uni-extra-color: #c7c7c7;     // 辅助说明

// 边框颜色(从深到浅)
$uni-border-1: #F0F0F0;
$uni-border-2: #EDEDED;
$uni-border-3: #DCDCDC;
$uni-border-4: #B9B9B9;

// 常规色
$uni-black: #000000;
$uni-white: #ffffff;
$uni-transparent: rgba($color: #000000, $alpha: 0);
$uni-bg-color: #f7f7f7;

3.3 间距、阴影与蒙版

/* 水平间距 */
$uni-spacing-sm: 8px;
$uni-spacing-base: 15px;
$uni-spacing-lg: 30px;

// 阴影
$uni-shadow-sm: 0 0 5px rgba($color: #d8d8d8, $alpha: 0.5);
$uni-shadow-base: 0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2);
$uni-shadow-lg: 0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5);

// 蒙版
$uni-mask: rgba($color: #000000, $alpha: 0.4);

两个基础变量值得单独说明:$uni-space-root: 2 是间距"基础倍数",所有间距类名的数值都要乘以它;$uni-radius-root: 5px 是圆角基础值。另外,_variables.scss 中还定义了一套完整的标题字号 map $uni-headings(h1 32px/300、h2 28px/300、h3 24px/400、h4 20px/400、h5 16px/400、h6 14px/500、subtitle 12px、body 14px、caption 12px),供文本排版类使用。

四、类名生成机制:一行类名搞定布局

4.1 间距类:uni-m{a|t|r|b|l|x|y}-{0..16}

_space.scss 用两层循环批量生成间距类:外层遍历 m(margin)和 p(padding),内层遍历方向 t/r/b/l/x/y/a(top/right/bottom/left/x 轴/y 轴/all),数值从 0 到 16。实际像素值 = $i * $uni-space-root,即 uni-mt-5 = margin-top: 10px(5 × 2)。同时每个正向类都配套生成负值类 -n 后缀版本(如 uni-mt-n5 = margin-top: -10px)。

以 pages/extUI/color/color.nvue 中的实际用法为例:

<view class="uni-ma-5">
	<view class="box uni-radius">
		<view class="item-box uni-primary-bg">
			<text class="uni-body uni-white">primary</text>
		</view>
	</view>
</view>

4.2 圆角类:uni-radius[-{方向}][-{档位}]

_radius.scss 基于 $uni-radius map 生成圆角类,档位定义如下:

档位 值
0(无后缀) 0
null(无档位) $uni-radius-root = 5px
lg 10px(root × 2)
xl 30px(root × 6)
pill 9999px(胶囊)
circle 50%(圆形)

方向支持 t/r/b/l/tl/tr/br/bl 八个方位,因此你可以写出 uni-radius-t-lg(顶部大圆角)、uni-radius-circle(圆形)等组合。sm 档被注释为 TODO 暂不支持,原因是其依赖 math.div() 除法计算。

4.3 颜色类:uni-{key} 与 uni-{key}-bg

_color.scss 将 30 个颜色变量(主色、辅助色、中性色、边框色、常规色的全部 key)通过 @each 批量生成前景色类与背景色类:

@each $key, $child in $uni-ui-color {
	.uni-#{$key} { color: $child; }
	.uni-#{$key}-bg { background-color: $child; }
}

于是 uni-primary 控制文字颜色、uni-primary-bg 控制背景色,uni-success、uni-warning、uni-error、uni-info 及 uni-main-color、uni-border-1 等一应俱全。同文件还固化了 uni-shadow-sm/base/lg 与 uni-mask 类。pages/extUI/color/color.nvue 页面就是这套色板的完整演示:主色、辅助色、中性色、分隔线、常规色、阴影六个区块逐一渲染。

4.4 文本排版类:uni-h1 ~ uni-h6、uni-body

_text.scss 遍历 $uni-headings map 生成 .uni-h1 到 .uni-caption 等排版类,每个类展开为 font-size / font-weight / line-height。这里有一个典型的平台差异处理:非 nvue 平台直接输出 .uni-h1 类;而 #ifdef APP-NVUE 分支下类名被限定为 .container .uni-h1(需放在 .container 容器内),以规避 nvue 样式作用域限制。

4.5 按钮体系:.uni-btn

_styles.scss(整体包裹在 #ifndef APP-NVUE 中)提供了一套完整的按钮样式,hello-uniapp 的 pages/extUI/button/button.vue 对此做了详尽演示。其设计要点:

  • 基础类 .uni-btn 定义默认外观,并通过 &::after { border: none; } 去掉原生 button 的伪元素边框(解决小程序/App 端按钮自带边框问题);
  • 通过 type 属性驱动配色:type="primary|success|warning|error|info" 分别调用 is-color() / is-plain() 两个 mixin;
  • 支持 plain(镂空,由 is-plain mixin 实现浅色背景 + 主题色文字边框)、loading、disabled 三种状态;
  • 尺寸控制:size="mini" 走原生尺寸,.uni-btn-small(14px)、.uni-btn-mini(12px)为类名微调,.uni-btn-radius 提供 999px 胶囊圆角。

所有按钮状态都基于主题色变量动态计算,例如禁用态通过 mix($color, #fff) 淡化背景、mix(darken($color,10%), #fff) 淡化边框,因此改一处主题变量即可让整套按钮风格随之变化。

五、主题定制:覆写变量与全局生效

uni-scss 的 !default 设计使其天然支持主题覆写。两种典型做法:

方式一:全局覆写(推荐)。在你项目根目录的 uni.scss 中先定义同名变量,再让 uni-app 自动注入。hello-uniapp 根目录的 uni.scss 本身就是一套独立的 uni-app 内置变量($uni-color-primary: #007aff 等),而 uni-scss 的变量($uni-primary)则服务于 uni-ui 组件体系。二者命名不同、职责互补——前者是 uni-app 框架内置约定,后者是 uni-ui 组件使用的辅助样式库。

方式二:局部覆写。在组件 <style lang="scss"> 内先声明变量再 @import '@/uni_modules/uni-scss/index.scss',可只影响该组件作用域。

从仓库证据看,uni-scss 的主题能力已被 uni-ui 组件广泛依赖:多个组件的 changelog 明确记载"支持使用 uni-scss 控制主题色"(如 uni-calendar/changelog.md、uni-data-checkbox/changelog.md、uni-data-picker/changelog.md);uni-pagination/changelog.md 还记录过一次"未对主题色设置默认色,导致未引入 uni-scss 变量文件报错"的修复,反证了变量体系对组件的重要性。此外 uni-badge、uni-card、uni-collapse、uni-countdown、uni-dateformat 等多个组件的 package.json 均把 uni-scss 声明为依赖,说明它是 uni-ui 组件族的公共样式底座。

六、快速上手清单

  1. 确认 HBuilderX 版本 ≥ 3.1.0(见 package.json 的 engines 声明);
  2. 在 App.vue 的 <style lang="scss"> 中 @import '@/uni_modules/uni-scss/index.scss';;
  3. 页面模板中直接使用辅助类:uni-mt-5、uni-px-2、uni-radius-lg、uni-primary-bg、uni-shadow-base、uni-btn 等;
  4. 需要换肤时,在引入前覆写 $uni-primary、$uni-success 等 !default 变量;
  5. nvue 页面注意条件编译差异(间距/颜色类可用,.uni-btn 按钮与部分排版类不生效);
  6. 参考仓库中的现成 demo:color.nvue 看色板与阴影,button.vue 看按钮全形态。

这套以"变量 + 类名生成循环"为核心的样式架构,用极少的源码量覆盖了页面开发中最频繁的样式诉求,也让主题定制成本降到最低——这正是它成为 uni-ui 组件族公共依赖的原因所在。

登录后查看全文
hello-uniapp