WeUI for 小程序上手指南:样式接入、rpx 适配与黑暗模式实战
WeUI for 小程序上手指南:样式接入、rpx 适配与黑暗模式实战
WeUI for 小程序(仓库名 weui-wxss)是一套由微信官方设计团队打造的基础样式库,目标是与微信原生视觉体验保持一致。本文以仓库 README.md 为骨架,结合 dist 与 src 双目录的源码与构建配置,系统讲解如何在微信小程序项目中接入全量或按需样式、如何选择 px 与 rpx 版本、如何通过 data-weui-theme 实现黑暗模式,以及如何用微信开发者工具打开示例工程。读完本文,你将能独立完成 WeUI 样式的引入、主题适配与示例预览。
概述:为微信小程序量身设计的基础样式库
WeUI 是一套同微信原生视觉体验一致的基础样式库,由微信官方设计团队为微信内网页和微信小程序量身设计,目的是让用户在不同入口中的使用感知更加统一。它覆盖了日常开发中最常用的一批界面元素,包括:
button(按钮):普通型、底部悬浮型、加载、禁用等状态cell(单元格):列表、表单、选择、开关、上传等形态dialog/half-screen-dialog/actionsheet:各类对话框与弹出菜单progress(进度条)、slider(滑块)、steps(步骤条)toast(轻提示)、top-tips(顶部提示)、information-bar(信息条)article(文章页)、msg(结果页)、panel(面板)、grid(宫格)icon(图标)、navbar/tabbar(导航)、searchbar(搜索条)、picker(选择器)等
从 src/style/weui.less 的 @import 列表可以看到,所有组件样式统一经过 src/style/base/fn.less 引入基础变量与 mixin,再按 widget 目录逐模块组织,最后聚合成一份完整的样式入口。需要说明的是,本仓库交付的是纯 UI 库(只包含样式与示例 WXML),不含逻辑封装;若需要带交互逻辑的组件版本,请使用微信官方提供的小程序组件库 WeUI。
快速开始:两种引入样式的方式
README 给出了两种接入方式,二者都以 dist 目录下的编译产物为准:
方式一:全量引入
直接引用编译好的总样式文件:
@import "weui-wxss/dist/style/weui.wxss";
在 app.wxss 中引入一次即可全局生效,package.json 的 main 字段也指向 dist/style/weui.wxss,说明该文件就是官方认定的入口样式。
方式二:按需引入
如果只需要个别组件,可以只引入 dist/style/widget 下对应组件的独立 wxss。该目录的组织与 src/style/widget 一一对应,例如:
widget/weui-button/:按钮相关(全局、primary、default、warn、disabled、loading、bottom-fixed 等)widget/weui-cell/:单元格、表单、switch、gallery、uploader 等widget/weui-tips/:actionsheet、dialog、toast、mask、toptips、badge 等
组件的 WXML 结构怎么看?
WeUI 只提供样式,不提供组件标签,因此你需要自己按官方给出的 WXML 结构组织页面。README 明确指出:组件的 wxml 结构请看 dist/example 下的示例页面。例如 dist/example/actionsheet/actionsheet.wxml 展示了 ActionSheet 的完整骨架:根节点 <view class="page">、遮罩 weui-mask、面板 weui-actionsheet、标题 weui-actionsheet__title、菜单 weui-actionsheet__menu 与负向菜单 weui-actionsheet__cell_warn。这些 class 均与 src/style/widget/weui-tips/weui-actionsheet.less 中的选择器一一对应,可直接复制进自己的页面。
认识 px 与 rpx 两个发行版本
README 特别提醒:默认版本使用的是 px,另提供 rpx 版本,位于 dist-rpx-mode 目录。
两者均由同一份 Less 源码构建而来,差异来自 gulpfile.js 中的 buildStyle 任务:
.pipe(rename((path) => { path.extname = '.wxss'; }))
.pipe(gulp.dest('dist')) // px 版本
.pipe(replace(/([\d.]+)px/g, (w, m) => `${2 * m}rpx`)) // rpx 版本
.pipe(gulp.dest('dist-rpx-mode'));
构建时先把 src/**/*.less 编译成 wxss 输出到 dist,随后用正则把所有 数值px 替换为 数值×2 rpx 再输出一份到 dist-rpx-mode。这与微信小程序的单位换算规则一致:在 375px 设计稿宽度下,1rpx = 0.5px,因此 16px 对应 32rpx。如果你的页面以 rpx 为布局单位(常见于 750 设计稿开发模式),直接引入 dist-rpx-mode 下的样式即可;否则使用默认的 dist。
黑暗模式:一行属性接入
README 给出的黑暗模式用法非常简洁:在根结点增加属性 data-weui-theme="dark",例如:
<view data-weui-theme="dark">
...
</view>
其底层原理是 CSS 变量(自定义属性)驱动的主题切换。看 src/style/base/theme/index.less:
page,
[data-weui-theme='light'] {
.varsLight();
}
[data-weui-theme='dark'] {
.varsDark();
}
也就是说,只要根节点带有 data-weui-theme="dark",该子树就会套用 src/style/base/theme/vars/dark.less 定义的一整套深色变量;不写属性或写 light 则使用 src/style/base/theme/vars/light.less 的浅色变量。
这套变量体系覆盖了背景、前景、品牌色、分隔线、状态层等,命名上以语义化前缀统一组织,例如:
--weui-BG-0~--weui-BG-5:页面各级背景色--weui-FG-0~--weui-FG-4:主次文本前景色(多使用带透明度的黑/白)--weui-BRAND(品牌绿,浅色为#07c160)、--weui-RED、--weui-ORANGE等语义色--weui-OVERLAY:遮罩色(浅色rgba(0,0,0,0.5),深色提升为rgba(0,0,0,0.8))
所有组件样式都通过 var(--weui-XXX) 消费这些变量,因此切换主题时无需改动组件样式。例如按钮组件 src/style/widget/weui-button/weui-btn_primary.less 的背景色直接取 var(--weui-BRAND);src/style/widget/weui-button/weui-btn_default.less 取 var(--weui-FG-0) 与 var(--weui-FG-5);src/style/widget/weui-tips/weui-mask.less 使用固定的半透明黑遮罩。此外 src/style/base/variable/weui-button.less 还通过 setColor 混入了按钮按压缩影等深浅两套色值。
在主题 mixin 层面,src/style/base/theme/fn.less 提供了 dark()、setColor()、setThisColor() 等工具,其中 setColor 会分别生成 page, [data-weui-theme='light'] 与 [data-weui-theme='dark'] 两套规则,便于组件在 Less 源码中定义"同一个变量、两套取值"。
在示例工程中如何动态切换主题
仓库的示例小程序将主题值放在 App.globalData 中统一管理(见 dist/app.js):
globalData: {
theme: 'light', // dark
mode: '', // 模式(care:关怀模式)
},
onThemeChange(resp) {
this.changeGlobalData({ theme: resp.theme });
},
每个页面通过 dist/mixin/common.js 这个 mixin 在 onLoad 时把 theme、mode 同步到页面的 data,并注册 onGlobalDataChanged 监听全局变化;WXML 根节点再把它绑定到属性上(见 dist/example/index.wxml):
<page-meta root-font-size="system"/>
<view class="page" data-weui-theme="{{theme}}" data-weui-mode="{{mode}}">
mixins 能力由 dist/libs/Mixins.js 提供,它会合并 mixin 的 data、生命周期方法与自定义属性,并在同名生命周期中先执行 mixin 再执行页面自身逻辑。示例中几乎所有页面(dist/example/actionsheet/actionsheet.wxml、dist/example/button/button.wxml 等)都遵循同一套 data-weui-theme + data-weui-mode 绑定模式。
扩展主题:关怀模式(适老化)
虽然 README 正文未展开介绍,但从源码结构可以推断,仓库还内置了"关怀模式"(适老化)支持:在 dist/app.js 与 dist/mixin/common.js 中都有 mode 字段,注释为"模式(care:关怀模式)";src/style/base/theme/index.less 中定义了:
[data-weui-mode='care'],
[data-weui-mode='care'][data-weui-theme='light'] {
.varsCareDark();
}
[data-weui-mode='care'][data-weui-theme='dark'] {
.varsCareDark();
}
即根节点同时设置 data-weui-mode="care" 时,会启用 src/style/base/theme/vars/care-dark.less(care-light 变量同样存在于源码,见 src/style/base/theme/vars/care-light.less)。关怀模式下的前景色对比度更高(如 --weui-FG-0: #000),更适合老年用户阅读。如果你的小程序需要适老化版本,可以在全局统一为根节点加上 data-weui-mode="care",无需改任何组件样式。
运行官方示例工程
README 强调:用微信开发者工具打开 dist 目录(请注意,是 dist 目录,不是整个项目)。也就是说,把 dist 作为一个小程序项目根目录导入开发者工具即可预览全部组件示例。
dist/app.json 中登记了完整的示例页面清单,覆盖表单(button、form、list、slideview、slider、uploader)、基础组件(article、badge、flex、footer、grid、icons、loading、panel、preview、progress、steps)、操作反馈(actionsheet、dialog、half-screen-dialog、msg、picker、toast、information-bar)、导航(navigation-bar、tabbar)与搜索(searchbar 及多种变体)。入口页 dist/example/index.wxml 以分类宫格的形式列出这些页面,点击即可跳转查看对应组件的 WXML 结构与样式效果。
如果你的项目也想复用这套示例工程的骨架(主题绑定、mixin 监听等),可以参照 dist/app.js 的 globalData 结构、dist/mixin/common.js 的页面 mixin 与 dist/libs/Mixins.js 的 Page 增强实现。
从源码构建:px/rpx 双版本是如何产出的
若你基于 src 下的 Less 源码二次开发(例如调整按钮圆角、自定义间距变量),可以本地构建出与仓库一致的 dist 与 dist-rpx-mode。构建依赖与脚本见 package.json:
npm install # 安装 gulp、gulp-less、postcss 等 devDependencies
npm run build # 等价于 gulp build,产出 dist 与 dist-rpx-mode
npm start # 等价于 gulp,构建并监听 src/**/* 变化,自动重新编译
gulpfile.js 的构建流程值得关注的三点:
- 样式编译(
buildStyle):Less → PostCSS(autoprefixer 目标为 iOS >= 8 / Android >= 4.1)→ cssnano 压缩 → 追加版本 banner → 输出dist,再经 px→rpx 替换输出dist-rpx-mode。 - 示例拷贝(
buildExample):把src下非 less 文件(wxml/js/json)同步到两个发行目录。 - 字号 rem 适配(
buildExampleStyle):将示例页面 wxss 中的font-size: Npx按客户端默认 17px 换算为rem,对应示例 WXML 顶部的<page-meta root-font-size="system"/>,保证系统级字体缩放下布局不塌。
因此日常开发推荐直接在 src 改 Less,让 gulp 的 watch 任务自动产出两个发行版本。
目录结构速览
- dist:px 版本的编译产物(推荐接入与小程序预览目录)
- dist-rpx-mode:rpx 版本的编译产物
- src:Less 样式源码与示例页源码(开发入口)
- src/style:样式源码,含
base(变量/主题/mixin/patch)、widget(按组件划分的样式)、icon与聚合入口 src/style/weui.less - src/example:示例页面源码
- src/style:样式源码,含
- gulpfile.js:构建脚本
- package.json:包信息与构建命令
- project.config.json / project.private.config.json:开发者工具项目配置
License 与贡献
本仓库遵循 MIT 协议(详见 LICENSE.txt),可以自由使用与参与开源。WeUI 的视觉标准以 weui-design 设计规范为参考。如果你有好的意见或建议,欢迎直接为本仓库提 issue 或 pull request。
小结
围绕 README 提供的几条核心指令,本文已经给出了完整闭环:全量/按需引入样式 → 参照 dist/example 组织 WXML → 选择 px(dist)或 rpx(dist-rpx-mode)版本 → 用 data-weui-theme="dark" 开启黑暗模式(可选 data-weui-mode="care" 开启关怀模式)→ 用微信开发者工具打开 dist 预览全部组件 → 必要时基于 src 的 Less 源码重新构建。这套体系的核心价值在于:所有组件样式通过 CSS 变量与主题属性解耦,主题切换与组件样式互不侵入,接入成本被压缩到"一个根节点属性"的级别。