- 前端
- UI组件
- 小程序
- 设计系统
- 移动开发
【免费下载链接】tdesign-miniprogram
Wechat MiniProgram and Uniapp UI components lib for TDesign
导读
本文以 TDesign Uniapp 组件库中 ColorPicker 颜色选择器组件的 API 文档为主线,系统梳理其属性(Props)、事件(Events)、插槽(Slots)与 CSS 变量四大部分,并结合 color-picker.vue 组件实现、props.ts 属性定义与 type.ts 类型声明等源码,逐项讲解每个配置项的取值约束、底层作用与典型使用场景。读完本文,你将能够独立完成基础色板、弹窗式、多格式色值等形态的颜色选择器接入,并利用 CSS 变量对组件视觉细节做细粒度定制。
ColorPicker 是 TDesign 表单类(form spline)组件,用于颜色选择,支持 HEX、RGB、HSL、HSV、CMYK、CSS 等多种色值格式输出。在仓库中其源码位于 packages/uniapp-components/color-picker 目录,组件主实现、内部模板(饱和度面板 / 色相滑块 / 透明度滑块 / 系统预设色板)、属性定义与类型声明分文件组织,结构清晰、便于按需研读。
引入方式与基础用法
通过 easycom 自动引入
中文版文档 README.md 推荐使用 easycom 模式引入组件,配置后无需手动import即可直接在模板中使用<t-color-picker />。
手动引入
如需手动引入组件,可以这样写:
import TColorPicker from '@tdesign/uniapp/color-picker/color-picker.vue';并在页面components中注册后使用。仓库示例目录 packages/uniapp-components/color-picker/_example 下提供了 base、multiple、format、use-popup 四套可直接运行的演示页面,下文实战部分会逐一展开。
ColorPicker Props 属性详解
组件全部属性均定义于 props.ts,其 TypeScript 类型声明见 type.ts。下表为完整属性清单:
| 名称 | 类型 | 默认值 | 描述 | 必传 | | -- | -- | -- | -- | -- | | custom-style | Object | - | 自定义样式 | N | | auto-close | Boolean | true | 自动关闭:点击遮罩层时自动关闭,无需手动设置 visible | N | | enable-alpha | Boolean | false | 是否开启透明通道 | N | | fixed | Boolean | false | 如果 color-picker 位于一个position:fixed区域,需显式指定为 true | N | | format | String | RGB | 格式化色值。enableAlpha为真时,HEX8/RGBA/HSLA/HSVA有效。可选项:HEX/HEX8/RGB/RGBA/HSL/HSLA/HSV/HSVA/CMYK/CSS | N | | popup-props | Object | {} | 透传 Popup 组件全部属性。TS 类型:PopupProps,见 Popup API 文档,类型定义见 type.ts | N | | swatch-colors | Array | undefined | 系统预设颜色样例。值为null或[]则不显示系统色;值为undefined会显示组件内置的系统默认色。TS 类型:Array<string> \| null \| undefined| N | | type | String | base | 选择器类型。可选项:base / multiple,type TypeEnum = 'base' \| 'multiple',类型定义见 type.ts | N | | use-popup | Boolean | false | 是否使用弹出层包裹颜色选择器 | N | | value | String | - | 色值。支持语法糖v-model:value| N | | default-value | String | - | 色值。非受控属性 | N | | visible | Boolean | false | 是否显示颜色选择器,usePopup为 true 时有效 | N |
format:输出色值格式
format决定组件最终输出的色值字符串格式,默认RGB。其合法取值在 props.ts 中通过validator做了白名单校验:['HEX', 'HEX8', 'RGB', 'RGBA', 'HSL', 'HSLA', 'HSV', 'HSVA', 'CMYK', 'CSS'],传入不在列表中的值会被判为非法。
注意格式与透明通道的联动关系:默认RGB不带 alpha 分量;仅当enableAlpha为true时,HEX8/RGBA/HSLA/HSVA这类携带透明通道的格式才有效。此外从源码看,CMYK与CSS属于特殊格式——CMYK需要经过 RGB 到 CMYK 的颜色空间转换(实现在 common/shared/color-picker/cmyk.js),而CSS会直接返回rgba()或渐变色字符串。
在 color-picker.vue 中,getFormatList维护了一张FORMAT_MAP映射表,将每种格式映射为对应的数值数组(HSV/HSVA 取color.getHsva(),HSL/HSLA 取color.getHsla(),CMYK 追加一位透明度,CSS/HEX 则直接取字符串),最终统一在末尾追加按百分比取整的透明度。因此切换format后,面板上的数值预览区会随之重算。
swatch-colors:系统预设色板
swatch-colors控制面板底部的系统预设色块。其取值语义较为特殊,在 color-picker.vue 的genSwatchList中处理如下:
- 传
undefined(不传):返回组件内置的默认系统色板,即 constants.ts 中的DEFAULT_SYSTEM_SWATCH_COLORS(10 个由浅到深的品牌蓝紫色系色值,如#F2F3FF、#0052D9、#001A57); - 传
null或空数组[]:返回空数组,隐藏系统预设色板; - 传入具体色值数组:直接使用该数组渲染色块。
模板层(template.vue)会在innerSwatchList非空时渲染横向可滚动的色块列表,点击色块会触发clickSwatch并更新当前颜色。
type:base 与 multiple 两种形态
type决定面板是否展示完整调色能力:
base:仅展示系统预设内容(即预设色板),不显示饱和度面板与滑块;multiple:展示完整色板(饱和度面板、色相滑块、可选的透明度滑块)与系统预设内容。
在 color-picker.vue 中,组件通过监听type变化维护isMultiple布尔值,模板据此用v-if="isMultiple"控制饱和度面板、滑块区域与格式预览的渲染。
use-popup、visible 与 auto-close:弹窗模式三件套
use-popup为true时,组件主体会被包裹进t-popup弹出层(见 color-picker.vue),此时:
visible用于受控管理弹出层显隐,且组件会通过update:visible事件同步内部状态,因此支持v-model:visible双向绑定;popup-props可透传 Popup 的全部属性(如showOverlay、zIndex、overlayProps、placement等)。Popup 组件本身的完整属性清单见 popup/README.md。源码中组件为 Popup 设置了默认值:z-index默认 11500、placement固定为 bottom、show-overlay默认 true;auto-close默认true:点击遮罩层时自动关闭弹窗,无需手动改visible。对应实现见 color-picker.vue,关闭时会同时触发close事件与update:visible事件。
值得留意的是,弹窗模式下组件的面板尺寸与拖拽坐标依赖真实渲染后的节点位置,因此组件在弹窗显示后延时约 350ms 再调用getEleReact()重新测量节点矩形(color-picker.vue),以保证与 Popup 300ms 过渡动画的时序衔接。
value / default-value:受控与非受控色值
value为受控属性,配合v-model:value使用;default-value为非受控属性,仅在初始化时生效。组件内部在created阶段以defaultValue || value || DEFAULT_COLOR的顺序初始化颜色,其中DEFAULT_COLOR为 constants.ts 中定义的#001F97。当value变化时,组件会重新执行init()同步内部颜色状态(color-picker.vue)。
custom-style 与 fixed
custom-style用于注入自定义样式,模板层将其与默认样式拼接后作用于面板根节点;fixed针对position:fixed场景:当组件被放在 fixed 定位的容器(如scroll-view、自定义弹层)内时,触摸坐标计算方式需要切换为相对视口计算。相关细节见下文 FAQ 章节。
ColorPicker Events 事件详解
组件支持三个事件,完整定义见 type.ts:
| 名称 | 参数 | 描述 | | -- | -- | -- | | change |(context: { value: string, context: { color: ColorObject; trigger: ColorPickerChangeTrigger }})| 选中的色值发生变化时触发。value为新色值;context.color为当前调色板控制器的色值对象;context.trigger为触发来源,type ColorPickerChangeTrigger = 'palette-hue-bar' \| 'palette-alpha-bar' \| 'preset'| | close |(context: { trigger: ColorPickerTrigger })| 弹窗关闭时触发,type ColorPickerTrigger = 'overlay'| | palette-bar-change |(context: { color: ColorObject })| 调色板控制器(饱和度面板、色相滑块、透明度滑块)的值变化时触发 |
ColorObject 结构
change与palette-bar-change携带的ColorObject是组件对外输出的颜色对象,定义如下:
interface ColorObject { alpha: number; // 透明度,0-1 css: string; // CSS 表示(rgba() 或渐变字符串) hex: string; // 十六进制色值 hex8: string; // 带透明度的十六进制色值 hsl: string; hsla: string; hsv: string; hsva: string; rgb: string; rgba: string; value: number; // HSV 的明度分量 }该对象的生成逻辑位于 common/shared/color-picker/color.js:getColorObject从内部Color实例上提取alpha/css/hex/hex8/hsl/hsla/hsv/hsva/rgb/rgba/saturation/value/isGradient等字段;若当前色为渐变色,还会额外补充linearGradient字段。也就是说,开发者在一个change回调中即可同时拿到十余种色值表示,无需自行转换。
trigger 来源与事件调用链
change事件的trigger在源码中由不同交互路径产生:
- 拖动色相滑块:触发
palette-hue-bar(对应onChangeSlider中isAlpha=false分支); - 拖动透明度滑块:触发
palette-alpha-bar(onChangeSlider中isAlpha=true分支); - 点击系统预设色块:触发
preset(对应clickSwatch方法)。
三个交互入口最终都会汇总到emitColorChange(trigger)(color-picker.vue),统一携带格式化后的value与ColorObject发出change事件;而饱和度面板与滑块的实时拖动过程则额外发出palette-bar-change,适合需要实时预览的场景(如弹窗模式下在 header 插槽中做实时色值展示)。
示例:监听 change 与 palette-bar-change
参考 multiple/index.vue:
<t-color-picker enable-alpha type="multiple" @change="onChange" @palette-bar-change="onPaletteBarChange" />onChange(e) { console.log('change', e); }, onPaletteBarChange(e) { console.log('onPaletteBarChange', e); },ColorPicker Slots 插槽
| 名称 | 描述 | | -- | -- | | footer | 底部插槽,仅在usePopup为true时有效 | | header | 顶部插槽,仅在usePopup为true时有效 |
从 color-picker.vue 可以看到,header插槽位于t-popup内部、模板面板之前,footer插槽位于面板之后,二者仅在usePopup分支中渲染。典型的应用场景是:在footer中放一个「确认/取消」按钮组,在header中放标题栏或当前色值预览。
CSS Variables 样式定制
组件通过 CSS 变量开放了面板、饱和度区域、滑块、色块等全部关键视觉参数,默认值定义于 color-picker.less,完整清单如下:
| 变量名 | 默认值 | 描述 | | -- | -- | -- | | --td-color-picker-gradient-preview-height | 56rpx | 渐变预览区高度 | | --td-color-picker-gradient-preview-radius | 6rpx | 渐变预览区圆角 | | --td-color-picker-gradient-preview-width | 56rpx | 渐变预览区宽度 | | --td-color-picker-input-format-margin-left | 48rpx | 格式输入区左外边距 | | --td-color-picker-panel-background | @bg-color-container | 面板背景色 | | --td-color-picker-panel-padding | 32rpx | 面板内边距 | | --td-color-picker-panel-radius | 24rpx | 面板圆角 | | --td-color-picker-panel-width | 750rpx | 面板宽度 | | --td-color-picker-saturation-height | 288rpx | 饱和度面板高度 | | --td-color-picker-saturation-radius | 12rpx | 饱和度面板圆角 | | --td-color-picker-saturation-thumb-size | 48rpx | 饱和度面板拖拽点尺寸 | | --td-color-picker-slider-height | 16rpx | 滑块轨道高度 | | --td-color-picker-slider-thumb-padding | 6rpx | 滑块拖拽点内边距 | | --td-color-picker-slider-thumb-size | 48rpx | 滑块拖拽点尺寸 | | --td-color-picker-slider-thumb-transform-x | -18rpx | 滑块拖拽点水平偏移 | | --td-color-picker-slider-wrapper-padding | 0 18rpx | 滑块容器内边距 | | --td-color-picker-swatch-border-radius | @radius-small | 预设色块圆角 | | --td-color-picker-swatch-height | 48rpx | 预设色块高度 | | --td-color-picker-swatch-padding | 0 | 预设色块内边距 | | --td-color-picker-swatch-width | 48rpx | 预设色块宽度 | | --td-color-picker-swatches-title-font | @font-title-medium | 系统预设色彩标题字体 |
这些变量在 color-picker.less 中以var(--td-xxx, 默认值)的形式被引用,因此通过覆盖同名变量即可在不动源码的前提下定制组件外观。例如将面板改为浅色圆角容器、缩小色块间距:
.t-color-picker { --td-color-picker-panel-radius: 16rpx; --td-color-picker-panel-width: 690rpx; --td-color-picker-swatch-width: 40rpx; --td-color-picker-swatch-height: 40rpx; }实战示例
1. 基础颜色选择器(base)
参考 base/index.vue,type默认为base,仅展示系统预设色板,点击色块即触发change:
<t-color-picker @change="onChange" />onChange(...args) { console.log('change:', ...args); }2. 带色板的完整选择器(multiple)
参考 multiple/index.vue,开启透明通道并切换到multiple形态后,会展示饱和度面板、色相滑块、透明度滑块、格式预览与系统预设色板:
<t-color-picker enable-alpha type="multiple" @change="onChange" @palette-bar-change="onPaletteBarChange" />3. 弹窗形式的选择器(use-popup)
参考 use-popup/index.vue,通过use-popup配合受控的visible实现点击按钮弹出选择器,并同步监听update:visible事件:
<t-color-picker :visible="visible" use-popup enable-alpha type="multiple" @update:visible="(e) => (visible = e)" @change="onChange" @palette-bar-change="onPaletteBarChange" />data() { return { visible: false }; }, methods: { handlePopup() { this.visible = true; }, },4. 多格式切换演示(format)
参考 format/index.vue,通过外部按钮组在CSS/HEX/RGB/HSL/HSV/CMYK等格式间切换,并把curFormat绑定到组件的format属性上:
<t-color-picker enable-alpha type="multiple" :format="curFormat" :value="color" @change="onChange" @palette-bar-change="onPaletteBarChange" />data() { return { curFormat: 'CSS', color: '#7bd60b', formatList: [ ['CSS', 'HEX', 'RGB'], ['HSL', 'HSV', 'CMYK'], ], }; },组件底层实现原理
Color 类:色值转换核心
组件的全部色值运算由 common/shared/color-picker/color.js 中的Color类承担。它内部维护 HSV 状态(s/v/h/a),并基于tinycolor2实现各色彩空间的互转:
- 内部状态为 HSV,饱和度面板拖拽改变
s(饱和度)与v(明度),色相滑块改变h,透明度滑块改变a; rgb/rgba/hsl/hsla/hsv/hsva/hex/hex8/cmyk/css均为基于该状态的 getter,输出对应格式字符串;getFormatsColorMap()一次性返回全部格式,供formatValue()按当前format取值(color-picker.vue)。
各 getter 的转换链也清晰可见:hsv2rgba、hsv2hsla走 tinycolor;CMYK 则通过 cmyk.js 的rgb2cmyk完成 RGB→CMYK 数学转换,并支持cmyk(r, g, b, k)字符串的反向解析(cmykInputToColor)。
拖拽坐标计算
饱和度面板与滑块的触摸交互统一由 color-picker.vue 的getCoordinate处理,结合节点测量结果计算拖拽位置:
- 普通场景:使用
e.currentTarget.offsetTop计算相对面板的偏移; usePopup或fixed场景:改用react.top(节点距视口顶部)与clientY计算,避免 fixed 定位下 offsetTop 失效;- 饱和度面板的拖拽结果换算为 0-1 的饱和度与明度(
getSaturationAndValueByCoordinate),滑块则按x/width * maxValue换算为色相(0-360)或透明度(0-100)数值。
FAQ:scroll-view 场景适配
如果 ColorPicker 的宿主页面使用了scroll-view,除了显式指定fixed为true外,还需要手动调用组件的debouncedUpdateEleRect()方法,以在滚动时持续校正面板节点位置(防止拖拽坐标漂移)。参考中文文档 README.md 与源码中的 updateEleRect(内部为 150ms 防抖):
<scroll-view type="list" scroll-y bind:scroll="onScroll"> <t-color-picker id="ColorPicker" fixed /> </scroll-view>onScroll(e) { if (!this.colorPicker) this.colorPicker = this.selectComponent('#ColorPicker'); this.colorPicker.debouncedUpdateEleRect(e); }小结
ColorPicker 组件以「预设色板 + 完整调色面板 + 多格式输出」的组合覆盖了移动端常见的颜色选择场景:base/multiple两种形态控制能力范围,use-popup三件套(visible/popup-props/auto-close)解决弹窗交互,format与enable-alpha组合决定输出格式,change/palette-bar-change/close事件则提供了从最终取值到实时预览的完整回调链。配合 21 个 CSS 变量,无需改动源码即可完成面板尺寸、圆角、色块等视觉细节的品牌化定制。若需在scroll-view等滚动容器中使用,牢记fixed+debouncedUpdateEleRect的组合即可规避坐标漂移问题。
- 前端
- UI组件
- 小程序
- 设计系统
- 移动开发
【免费下载链接】tdesign-miniprogram
Wechat MiniProgram and Uniapp UI components lib for TDesign
相关推荐
Element UI 颜色选择器 ColorPicker 组件详解
Element UI 颜色选择器 ColorPicker 组件详解 组件概述 Element UI 的 ColorPicker 是一个功能强大的颜色选择器组件,
前端UI组件设计系统BootstrapBlazor颜色选择器:ColorPicker组件使用详解
BootstrapBlazor颜色选择器:ColorPicker组件使用详解 1. 组件概述 ColorPicker(颜色选择器)是BootstrapBlazo
UI组件前端Element Plus颜色选择器:ColorPicker颜色选择与自定义
Element Plus颜色选择器:ColorPicker颜色选择与自定义 前言:为什么需要专业的颜色选择器? 在现代Web开发中,颜色选择不仅仅是简单的RGB
前端UI组件
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考