Page 1 of 1

如何去自定义修改SmartUI组件的样式

Posted: 2026年 Feb 6日 10:28
by xiaoqi

前言

开发中常需调整组件样式(间距、颜色等),会涉及样式覆盖与 CSS 变量。本文说明如何正确修改 SmartUI 组件样式。


一、组件结构说明

SmartUI 基于 Web Component,Ray 在编译时会为每个原生组件外层生成唯一的标签名,命名规则为:{组件目录名}-{文件名}-{路径哈希},其中路径哈希是组件完整路径的 MD5 值(取前6位),用于确保不同来源的同名组件不会产生冲突。例如:

  • 项目自定义组件:src/components/nav-bar/index → nav-bar-index-abc123
  • npm 包组件:node_modules/@tuya-miniapp/smart-ui/dist/nav-bar/index → nav-bar-index-404ec1

所以 SmartUI 组件外层都会有一个 行内样式的标签,可视为一个普通的行内 view

以 NavBar 为例,在 Ray 上的 DOM 结构为:

544756333-e8c47f93-cf77-4512-b466-691eeedb1634.png

Code: Select all

<nav-bar-index-404ec1>
  <!-- 组件内部内容 -->
  <view class="smart-nav-bar">
  ...
  </view>
</nav-bar-index-404ec1>

要点:样式要生效,需作用到内部的 view 等节点,而非仅作用在外层组件标签上。


二、三种样式覆盖属性

除组件自带的 CSS 控制属性外,SmartUI 组件统一提供 classNamecustomClasscustomStyle 三个属性,用于样式覆盖。

2.1 className

作用位置:仅挂载在外层组件标签(如 <nav-bar-index-404ec1>)上,不直接作用到内部节点。

若只给该节点设样式(如背景色),内部看不到效果:

Code: Select all

<NavBar title="Smart UI 首页" className="myNavBar" />

Code: Select all

// app.less
.myNavBar {
  background-color: red; /* 无效:只作用在外层容器 */
}
544761871-8c1c85ca-992b-43c5-ac8d-a3abf68fa6f4.png

正确用法:在 className 对应的 class 下,写子选择器命中内部 class(如 .smart-nav-bar):

Code: Select all

// app.less
.myNavBar {
  .smart-nav-bar {
    background-color: red;
  }
}
544764391-b95147ef-9997-47dc-9b78-a94c4de107d0.png

注意:若在全局直接写 .smart-nav-bar { ... },会因选择器权重低于组件内部样式而被覆盖,但是也不推荐用 !important,建议通过上述「父 class + 子 class」或后文 CSS 变量方式覆盖。

若使用 CSS Modules,内部 class 需用 :global() 包裹,否则会被编译成带 hash 的 class,无法命中组件内部:

Code: Select all

<NavBar title="Smart UI 首页" className={styles.myNavBar} />

Code: Select all

// index.module.less
.myNavBar {
  :global(.smart-nav-bar) {
    background-color: red;
  }
}
544776431-8a17e236-7442-489d-80f5-492bc37c92a6.png

2.2 customClass

作用位置:组件内部预留的「自定义 class 位」,对应 DOM 上的 custom-class,一般挂在第一个内部根节点。传入的 class 会替换/合并到该位置。

Code: Select all

<View className={styles.container}>
  <NavBar title="Smart UI 首页" customClass={styles.myNavBar} />
</View>

Code: Select all

// index.module.less
.container {
  .myNavBar {
    background-color: red;
  }
}
544784256-8c9aee68-7b6b-465e-9de1-bd1fd9e664bd.png

注意

  • DOM 上仍会显示 custom-class,实际样式已由传入的 class 生效,以最终渲染效果为准。
  • 注入的 class 权重低于组件自身 class,单独写 .myNavBar { background-color: red } 可能被覆盖,可放在父级选择器下(如 .container .myNavBar)提高权重。

若去掉外层 .container,仅用 customClass={styles.myNavBar} 且全局只写 .myNavBar,会无法覆盖:

544786639-620142b7-f21b-4385-9054-07e34f03e4ce.png

2.3 customStyle

作用位置:一般是组件内部根元素的内联样式(不包含外层组件标签)。因小程序限制不能直接用 style 属性,故命名为 customStyle

直接修改内部根节点样式,无需关心 class 权重:

Code: Select all

<NavBar
  title="Smart UI 首页"
  customStyle={{
    backgroundColor: "red",
  }}
/>
544791165-7e8c7122-4900-4e8a-b3e9-f5e9678d2878.png

适合快速微调单个组件的外观。


2.4 如何判断样式来源

调试时可根据选择器特征判断样式来自哪里:

来源选择器特征
SmartUI组件自身样式.c-{随机串}-{组件 class}
项目内全局 less.{组件 class}(无随机串)
项目内 CSS Module 覆盖.{你的 class}__{随机串} .{组件 class}
544778329-702d3d1a-17b1-4050-9ebe-9216fe64552b.png
544777961-bdbbd05b-268c-451e-be92-f89584131d56.png
544777533-08cb66f5-54e3-4fb7-9ce4-9a90270ea3f8.png

三、CSS 变量覆盖(推荐)

组件内部预留了丰富的 CSS 变量, SmartUI 是不会定义这些 CSS 变量的值的,只是预留的空引用,所以开发者可以轻松在任何位置覆盖他们,不受 class 隔离影响,推荐优先使用

3.1 全局修改

在全局 less 或页面顶层样式中设置变量:

Code: Select all

// app.less
:root {
  --nav-bar-background-color: red;
}
544798128-dc8fcf65-ce48-44e4-b948-f8226e1c45cc.png

3.2 局部修改

配合 className,在对应 class 下覆盖变量,只影响该实例:

Code: Select all

<NavBar title="Smart UI 首页" className="myNavBar" />

Code: Select all

// app.less
.myNavBar {
  --nav-bar-background-color: red;
}

CSS Module 中同样在 className 对应的 class 下写变量即可:

Code: Select all

<NavBar title="Smart UI 首页" className={styles.myNavBar} />

Code: Select all

// index.module.less
.myNavBar {
  --nav-bar-background-color: red;
}

3.3 配合 ConfigProvider

主题级配置可使用 ConfigProvider 的 themeVars

Code: Select all

<ConfigProvider
  themeVars={{
    navBarBackgroundColor: "red",
  }}
>
  <NavBar title="Smart UI 首页" />
</ConfigProvider>

详细用法见:ConfigProvider 组件最佳实践
SmartUI Wiki:如何去自定义修改SmartUI组件的样式


Re: 如何去自定义修改SmartUI组件的样式

Posted: 2026年 Feb 6日 11:02
by lshinylee

🆙


Re: 如何去自定义修改SmartUI组件的样式

Posted: 2026年 Feb 6日 13:39
by ziyang

不错不错

👍🏻 :lol: :lol: :lol: :lol: :lol: :lol: