Element ColorPicker 颜色选择器组件完全指南:用法、参数与源码原理
【免费下载链接】elementA Vue.js 2.0 UI Toolkit for Web项目地址: https://gitcode.com/gh_mirrors/eleme/element
Element 的el-color-picker颜色选择器组件用于让用户从可视化面板中选取颜色,支持 Hex、RGB、HSL、HSV 等多种格式的解析与输出,并可搭配透明度(Alpha 通道)与预定义色板使用。本文基于 Element 官方中文文档(examples/docs/zh-CN/color-picker.md),结合仓库内组件源码与单元测试,完整讲解其用法、属性/事件参数,并深入剖析其颜色模型与面板实现原理,帮助你既能快速上手,也能理解底层工作机制。
快速上手:基础用法
ColorPicker 最核心的用法是通过v-model与 Vue 实例中的字符串变量进行双向绑定,绑定的变量需要是字符串类型。组件会在面板中确认颜色后,将格式化后的颜色字符串写回该变量。
<div class="block"> <span class="demonstration">有默认值</span> <el-color-picker v-model="color1"></el-color-picker> </div> <div class="block"> <span class="demonstration">无默认值</span> <el-color-picker v-model="color2"></el-color-picker> </div> <script> export default { data() { return { color1: '#409EFF', color2: null } } }; </script>- 当
color1有默认值(如'#409EFF')时,组件触发器会直接显示该颜色; - 当
color2为null时,触发器上会显示一个带el-icon-close的空态图标(见 main.vue 中!value && !showPanelColor的模板判断)。
从源码看,组件的valueprop 被声明为String类型,并在mounted时通过this.color.fromString(value)将初始值解析进内部颜色模型(main.vue);同时watch监听value,当外部传入的新值与内部color.value不一致时重新解析(main.vue)。确认颜色后,组件通过confirmValue依次触发input、change事件,并向 FormItem 派发el.form.change(main.vue),这也是它能无缝配合el-form校验的原因。
选择透明度:show-alpha
ColorPicker 不仅支持普通不透明颜色,还支持带 Alpha 通道的颜色。通过show-alpha属性(布尔值,默认false)即可控制是否支持透明度的选择。开启后,面板底部会多出一条透明度滑轨,同时触发器的颜色块上会叠加棋盘格背景以示透明区域。
<el-color-picker v-model="color" show-alpha></el-color-picker> <script> export default { data() { return { color: 'rgba(19, 206, 102, 0.8)' } } }; </script>开启show-alpha后,组件的默认输出格式会从hex自动切换为rgb(即rgba(...)字符串),这一点在官方 Attributes 表格的color-format默认值中明确标注。
在源码层面,showAlpha会被传入两个地方:
- 内部颜色模型:
data()中构造Color实例时以enableAlpha: this.showAlpha初始化(main.vue),决定color.value输出是否携带 alpha; - 下拉面板:面板中
alpha-slider仅在showAlpha为真时渲染(见 picker-dropdown.vue)。
透明度滑块的核心实现位于 alpha-slider.vue:其背景是一个从rgba(r, g, b, 0)到rgba(r, g, b, 1)的线性渐变(getBackground方法),用户拖动时通过this.color.set('alpha', ...)将 0~100 的百分比写回颜色模型。
预定义颜色:predefine
当需要提供一组快捷颜色供用户一键选取时,可使用predefine属性(数组类型)传入预定义色板。示例中给出了十分丰富的预定义数组,几乎覆盖了所有受支持的字符串格式:
<el-color-picker v-model="color" show-alpha :predefine="predefineColors"> </el-color-picker> <script> export default { data() { return { color: 'rgba(255, 69, 0, 0.68)', predefineColors: [ '#ff4500', '#ff8c00', '#ffd700', '#90ee90', '#00ced1', '#1e90ff', '#c71585', 'rgba(255, 69, 0, 0.68)', 'rgb(255, 120, 0)', 'hsv(51, 100, 98)', 'hsva(120, 40, 94, 0.5)', 'hsl(181, 100%, 37%)', 'hsla(209, 100%, 56%, 0.73)', '#c7158577' ] } } }; </script>可见预定义色板支持:
| 格式 | 示例 |
|---|---|
| Hex(6 位) | #ff4500 |
| Hex(8 位,含 Alpha) | #c7158577 |
| rgb / rgba | rgb(255, 120, 0)、rgba(255, 69, 0, 0.68) |
| hsv / hsva | hsv(51, 100, 98)、hsva(120, 40, 94, 0.5) |
| hsl / hsla | hsl(181, 100%, 37%)、hsla(209, 100%, 56%, 0.73) |
预定义面板的实现位于 predefine.vue:每个预定义色块都会被解析为一个独立的Color实例(强制开启enableAlpha并以rgba为内部格式),点击色块时执行this.color.fromString(this.colors[index])将颜色载入面板;当面板当前颜色变化时,通过Color.compare方法(色相误差 < 2、饱和度/明度/透明度误差 < 1)高亮当前选中的预定义色块。
不同尺寸:size
ColorPicker 与 Element 其他表单类组件一致,支持通过size属性控制触发器尺寸,可选值为medium/small/mini:
<el-color-picker v-model="color"></el-color-picker> <el-color-picker v-model="color" size="medium"></el-color-picker> <el-color-picker v-model="color" size="small"></el-color-picker> <el-color-picker v-model="color" size="mini"></el-color-picker> <script> export default { data() { return { color: '#409EFF' } } }; </script>从源码看,尺寸的解析顺序是有优先级的:组件自身的sizeprop 优先,其次继承el-form-item注入的elFormItemSize,最后回退到$ELEMENT.size全局配置(main.vue)。对应的尺寸类名形如el-color-picker--medium,具体样式由packages/theme-chalk/src/color-picker.scss定义。
属性(Attributes)全解析
官方文档给出的完整属性表如下:
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---|---|---|---|---|
| value / v-model | 绑定值 | string | — | — |
| disabled | 是否禁用 | boolean | — | false |
| size | 尺寸 | string | medium / small / mini | — |
| show-alpha | 是否支持透明度选择 | boolean | — | false |
| color-format | 写入 v-model 的颜色的格式 | string | hsl / hsv / hex / rgb | hex(show-alpha 为 false)/ rgb(show-alpha 为 true) |
| popper-class | ColorPicker 下拉框的类名 | string | — | — |
| predefine | 预定义颜色 | array | — | — |
这些 prop 在 main.vue 中一一对应声明,同时也在 TypeScript 类型定义 types/color-picker.d.ts 中通过ColorFormat = 'hsl' | 'hsv' | 'hex' | 'rgb'给出了color-format的字面量联合类型。
关于color-format需要特别说明的是:它只决定写入 v-model 的字符串格式,而面板交互本身不感知格式。例如把color-format设为hsl,确认后绑定的值就是hsl(210, 100%, 56%)这种形式;配合show-alpha时则会输出hsla(...)。这一输出逻辑完全由内部Color类的doOnChange方法根据format字段分派(见下节)。
disabled同样支持从外层el-form的disabled状态继承(this.disabled || (this.elForm || {}).disabled,见 main.vue),禁用后触发器上方会覆盖一层el-color-picker__mask遮罩并阻止点击展开。
事件(Events)
| 事件名称 | 说明 | 回调参数 |
|---|---|---|
| change | 当绑定值变化时触发 | 当前值 |
| active-change | 面板中当前显示的颜色发生改变时触发 | 当前显示的颜色值 |
两个事件的触发时机在源码中非常清晰:
- change:仅在用户点击面板“确定”按钮(或通过输入框回车/失焦确认后点确定)时触发。
confirmValue中先$emit('input', value)更新 v-model,再$emit('change', value)(main.vue);点击“清除”按钮则触发input(null)与change(null)(main.vue)。即:只要用户没有点确定,拖拽过程中的颜色不会污染 v-model; - active-change:在面板展开状态下,只要触发块显示的颜色与当前 v-model 值不一致,就实时触发(main.vue)。该事件常用于需要“实时预览但延迟提交”的场景。
单元测试 test/unit/specs/color-picker.spec.js 对这两个交互路径均有覆盖,例如点击触发器后.el-color-dropdown出现、点击确定按钮后vm.color变为#FF0000、开启show-alpha后.el-color-alpha-slider出现等。
源码原理:内部 Color 模型与颜色格式转换
要真正理解 ColorPicker 的行为(尤其是各种字符串格式的互转、color-format的输出差异),需要阅读其核心 color.js。该文件实现了一个独立的Color类,内部统一以HSV + Alpha四元组(_hue、_saturation、_value、_alpha,后三者以 0~100 百分比存储)作为唯一事实来源,对外再按需输出不同格式字符串。
字符串解析(fromString)
fromString(value)会根据字符串前缀自动识别格式并统一折算到 HSV:
hsl(...)/hsla(...):先经hsl2hsv换算;hsv(...)/hsva(...):直接取用;rgb(...)/rgba(...):先经rgb2hsv换算;#开头的 Hex:支持 3 位简写、6 位标准、8 位带 Alpha(如#c7158577),8 位时_alpha由parseHexChannel(hex.substring(6)) / 255 * 100计算;不匹配^(?:[0-9a-fA-F]{3}){1,2}|[0-9a-fA-F]{8}$的非法输入会被直接忽略(color.js)。
这解释了为什么预定义色板能同时接受 Hex、rgb、hsl、hsv 混排的数组——它们最终都被归一化为 HSV 内部状态。
格式输出(doOnChange)
doOnChange根据enableAlpha与format的组合决定输出字符串(color.js):
| enableAlpha | format | 输出示例 |
|---|---|---|
| false | hex(默认) | #409EFF |
| false | rgb | rgb(64, 158, 255) |
| false | hsl | hsl(210, 100%, 56%) |
| false | hsv | hsv(210, 100%, 100%) |
| true | 默认(rgb) | rgba(64, 158, 255, 0.8) |
| true | hsl | hsla(210, 100%, 56%, 0.8) |
| true | hsv | hsva(210, 100%, 100%, 0.8) |
其中 HSV→RGB 使用经典的扇形查表算法hsv2rgb,RGB→Hex 使用toHex,并处理了 1.0/100% 等价、浮点舍入误差(bound01)等边界情况。
面板结构
下拉面板 picker-dropdown.vue 由四部分拼装而成:
- sv-panel:二维取色板,横向是饱和度、纵向是明度,背景色随当前色相变化(
hsl(hue, 100%, 50%)),拖动时按坐标换算saturation与value(sv-panel.vue); - hue-slider:垂直色相滑轨,将滑动位置线性映射到 0~360 的色相值(hue-slider.vue);
- alpha-slider:透明度滑轨(
show-alpha时出现); - predefine:预定义色板(
predefine时出现)。
面板底部还内置了一个el-input文本框,支持直接输入任意格式的颜色字符串,回车或失焦后调用color.fromString(customInput)即时解析生效。所有滑块(取色板、色相、透明度)的拖拽行为统一由 draggable.js 封装:通过mousedown挂载mousemove/mouseup监听,拖拽期间禁用onselectstart与ondragstart防止文本选中,且对服务端渲染(Vue.prototype.$isServer)直接跳过,保证 SSR 场景安全。
与表单及 TypeScript 的集成
- 表单集成:ColorPicker 通过
inject注入elForm/elFormItem,既继承外层禁用与尺寸状态,也在确认/清除颜色时dispatch('ElFormItem', 'el.form.change', value)通知表单触发校验,因此可以直接放进el-form-item中参与表单验证。 - 类型支持:types/color-picker.d.ts 声明了
ElColorPicker组件类及ColorFormat联合类型;组件通过 index.js 以Vue.component方式全局注册(组件名为ElColorPicker),也可按需引入。
小结
ColorPicker 看似只是一个取色按钮,但其内部凝聚了完整的颜色科学工程:以 HSV 为统一模型打通 Hex/RGB/HSL/HSV 四种字符串格式的双向转换,以四个可拖拽子面板组合出完整的取色交互,并通过input/change/active-change三个事件精确区分"预览"与"提交"语义。掌握官方文档中的 7 个属性与 2 个事件,再对照 packages/color-picker/src 下的源码逐一印证,你就能在项目中灵活运用,甚至基于它扩展出自定义取色器。
【免费下载链接】elementA Vue.js 2.0 UI Toolkit for Web项目地址: https://gitcode.com/gh_mirrors/eleme/element
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考