自定义调色盘组件
示例效果调色盘组件代码使用input[typecolor]实现template div classcolor-plate-page div classcolor-div click.stoponColorDivClick/div div classcolor-plate v-ifplateVisible refcolorPlateRef div标准颜色/div div classflex-start stylemargin: 6px 0px div classstandard-color-item v-for(scolor, idx) in standardColors :keystandard-color-item${idx} :style{ backgroundColor: scolor } clickonStandardColorClick(scolor) /div /div div stylecursor: pointer clickinputColorRef?.click?.()更多颜色.../div input classhidden-color-input :valuecolor inputupdateColor typecolor refinputColorRef / /div /div /template script setup langts // 定义组件的 props 和 emits const props defineProps({ color: { type: String, default: #000000 } }); const emit defineEmits([update:color]); // 调色盘面板 const plateVisible refboolean(false); // input[typecolor] ref引用 const inputColorRef refany(null); // 标准颜色 const standardColors [ #C00000, // 深红 #FF0000, // 红色 #FFC000, // 橙色 #FFFF00, // 黄色 #92D050, // 浅绿 #00B050, // 绿色 #00B0F0, // 浅蓝 #0070C0, // 蓝色 #002060, // 深蓝 #7030A0 // 紫色 ]; // 挂载时监听全局点击事件 onMounted(() { document.addEventListener(click, onClickOutside); }); // 卸载时移除监听防止内存泄漏 onUnmounted(() { document.removeEventListener(click, onClickOutside); }); // color-div点击事件 const onColorDivClick () { plateVisible.value !plateVisible.value; nextTick(() { inputColorRef.value.value formattedColor.value; }); }; // 同步更新v-model值 const updateColor (event: any) { emit(update:color, event.target.value); }; // 标准颜色item点击事件 const onStandardColorClick (color: any) { emit(update:color, color); plateVisible.value false; }; // 全局点击事件处理点击空白处关闭调色盘面板 const colorPlateRef refany(null); const onClickOutside (e: MouseEvent) { if (!!plateVisible.value) { // 判断点击不在面板内即“空白处”→ 关闭面板 const isClickInPlate colorPlateRef.value?.contains(e.target as Node); if (!isClickInPlate) { plateVisible.value false; } } }; // 格式化颜色值input只支持 6 位十六进制解决 3 位缩写/格式不规范问题 const formattedColor computed(() { const colorMap: any { // 基础颜色 black: #000000, white: #ffffff, gray: #808080, // 标准gray对应的十六进制值 grey: #808080, // 兼容英式拼写 red: #ff0000, green: #008000, blue: #0000ff, skyblue: #87ceeb, yellow: #ffff00, orange: #ffa500, purple: #800080, pink: #ffc0cb, brown: #a52a2a, // 扩展灰度色可选 lightgray: #d3d3d3, darkgray: #a9a9a9 }; // ------------- const color props.color.trim(); const isHex color.startsWith(#); // 是否为hex色值 /^#([0-9a-fA-F]{6})$/.test(color) let ret color; if (isHex) { // 处理 3 位缩写如 #f00 → #ff0000 if (/^#([0-9a-fA-F]{3})$/.test(color)) { const [, r, g, b] color.match(/^#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])$/)!; ret #${r}${r}${g}${g}${b}${b}; } // 补全 6 位如 #000 → #000000 if (/^#([0-9a-fA-F]{1,5})$/.test(color)) { ret #${color.slice(1).padEnd(6, 0)}; } } else { // 处理颜色单词 ret colorMap[color]; } return ret || #000000; }); /script style langless scoped .color-plate-page { position: relative; .color-div { width: 24px; height: 24px; background-color: v-bind(props.color || #2770d4); border: 1px solid v-bind(props.color#ffffff ? #ccc:transparent); } .color-plate { position: absolute; padding: 6px 6px 6px 10px; margin-top: 8px; background-color: #fff; border: 1px solid #eee; box-shadow: 0 0 3px #eee; border-radius: 4px; z-index: 1040; .standard-color-item { width: 15px; height: 15px; margin-right: 3px; cursor: pointer; } // 隐藏的color input关键不可用display:none否则无法触发点击 .hidden-color-input { position: absolute; width: 0; height: 0; opacity: 0; pointer-events: none; // 避免遮挡点击 } } } /style父组件引用调色盘组件SColorPlate v-model:colorcolor /
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2459226.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!