直接改 $uni-color-primary 需在 uni.scss 中操作,并同步更新 js 常量、css 变量及所有引用处;否则按钮变色而弹窗确认色不变。js 须通过 variables.module.scss 桥接读取,app 端需用 css 变量+class 切换+原生 api 才能动态换肤。

直接改 $uni-color-primary 就行,但必须在 uni.scss 里改,且要确保所有用到它的组件、样式、JS 逻辑都同步适配——否则会出现「按钮变色了,弹窗确认按钮还是旧色」这类割裂现象。
为什么改了 $uni-color-primary 但部分组件没变
因为 uni-app 的官方组件(如 uni-button、uni-badge)只读取 uni.scss 中定义的 SCSS 变量,但以下三类情况不会自动响应:
- JS 中硬编码的颜色值,比如
confirmColor: '#007aff'(uni.showModal等 API 参数) - 内联
:style绑定,如:style="{ color: primaryColor }"—— 这种写法绕过了 SCSS 编译,不感知变量变更 - 自定义组件中未使用
lang="scss"或未@import变量文件,导致无法访问$uni-color-primary
如何让 JS 代码也能用上 $uni-color-primary
SCSS 变量不能直接在 JS 中读取,得靠 variables.module.scss + 模块导出实现桥接:
- 新建
src/styles/variables.module.scss,内容为:$uni-color-primary: #007aff;<br>:export {<br> primaryColor: $uni-color-primary;<br>} - 在 JS 中导入:
import variables from '@/styles/variables.module.scss',然后用variables.primaryColor - 注意:Vite 项目需在
vite.config.ts中启用css.modules支持(uni-app 3.8+ 默认支持,老版本需手动配) - 别用
require('@/styles/variables.module.scss')—— CommonJS 方式在 Vite 下不解析 :export
App 端换肤时 $uni-color-primary 不生效的真正原因
App 端(iOS/Android)用的是原生渲染器,编译后的 CSS 是静态注入的,改 SCSS 变量本身不会触发重绘。所以仅改 $uni-color-primary 并重新编译,对已运行的 App 无效。
- 动态换肤必须配合 CSS 变量(
--primary-color)+ class 切换,例如:<view class="theme-{{ currentTheme }}"></view> -
uni.scss里的$uni-color-primary仅影响构建时生成的默认样式,适合「打包即定主题」;若要运行时切换,它只是初始值来源,不是驱动源 - 导航栏、tabBar 等原生区域必须调用
uni.setNavigationBarColor()、uni.setTabBarStyle()单独设置,它们完全不读 SCSS 变量
最简落地建议:一套配置,三处落点
别只盯着 uni.scss,真正管用的是「SCSS 变量 + CSS 变量 + JS 常量」三位一体:
-
uni.scss定义$uni-color-primary: #007aff→ 供所有lang="scss"样式使用 -
App.vue <style></style>中定义:root { --primary-color: #007aff; }→ 供 class 切换和 :style 绑定 -
src/config/theme.ts导出export const PRIMARY_COLOR = '#007aff'→ 供 JS 逻辑、API 调用、条件判断使用
这三者初始值保持一致,换肤时再统一更新,才能避免颜色错位。最容易被忽略的是:JS 层用了新色,但 uni.showModal 的 confirmColor 还是写死的老值。











